Add CodeViewRecordBuildId

Until now we've been stuffing ELF debug symbol link information into a
CodeViewPDB70. This has reached the limits of its usefulness. We now add
a CodeViewRecord that can contain a proper ELF build ID.

Change-Id: Ice52cb2a958a1b9031943f280d9054da02d2f17d
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1574107
Commit-Queue: Casey Dahlin <sadmac@google.com>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Casey Dahlin 2019-04-17 22:01:50 -07:00 committed by Commit Bot
parent a7859e9bc6
commit 5f77cf41b6
21 changed files with 603 additions and 180 deletions

View File

@ -31,8 +31,7 @@
namespace crashpad {
MinidumpModuleCodeViewRecordWriter::~MinidumpModuleCodeViewRecordWriter() {
}
MinidumpModuleCodeViewRecordWriter::~MinidumpModuleCodeViewRecordWriter() {}
namespace internal {
@ -45,8 +44,7 @@ MinidumpModuleCodeViewRecordPDBLinkWriter<
template <typename CodeViewRecordType>
MinidumpModuleCodeViewRecordPDBLinkWriter<
CodeViewRecordType>::~MinidumpModuleCodeViewRecordPDBLinkWriter() {
}
CodeViewRecordType>::~MinidumpModuleCodeViewRecordPDBLinkWriter() {}
template <typename CodeViewRecordType>
size_t
@ -82,8 +80,7 @@ template class internal::MinidumpModuleCodeViewRecordPDBLinkWriter<
CodeViewRecordPDB20>;
MinidumpModuleCodeViewRecordPDB20Writer::
~MinidumpModuleCodeViewRecordPDB20Writer() {
}
~MinidumpModuleCodeViewRecordPDB20Writer() {}
void MinidumpModuleCodeViewRecordPDB20Writer::SetTimestampAndAge(
time_t timestamp,
@ -100,8 +97,7 @@ template class internal::MinidumpModuleCodeViewRecordPDBLinkWriter<
CodeViewRecordPDB70>;
MinidumpModuleCodeViewRecordPDB70Writer::
~MinidumpModuleCodeViewRecordPDB70Writer() {
}
~MinidumpModuleCodeViewRecordPDB70Writer() {}
void MinidumpModuleCodeViewRecordPDB70Writer::InitializeFromSnapshot(
const ModuleSnapshot* module_snapshot) {
@ -115,15 +111,52 @@ void MinidumpModuleCodeViewRecordPDB70Writer::InitializeFromSnapshot(
SetUUIDAndAge(uuid, age);
}
MinidumpModuleCodeViewRecordBuildIDWriter::
MinidumpModuleCodeViewRecordBuildIDWriter()
: MinidumpModuleCodeViewRecordWriter(), build_id_() {}
MinidumpModuleCodeViewRecordBuildIDWriter::
~MinidumpModuleCodeViewRecordBuildIDWriter() {}
size_t MinidumpModuleCodeViewRecordBuildIDWriter::SizeOfObject() {
DCHECK_GE(state(), kStateFrozen);
return offsetof(CodeViewRecordBuildID, build_id) + build_id_.size();
}
void MinidumpModuleCodeViewRecordBuildIDWriter::SetBuildID(
const std::vector<uint8_t>& build_id) {
DCHECK_EQ(state(), kStateMutable);
build_id_ = build_id;
}
bool MinidumpModuleCodeViewRecordBuildIDWriter::WriteObject(
FileWriterInterface* file_writer) {
DCHECK_EQ(state(), kStateWritable);
CodeViewRecordBuildID cv;
cv.signature = CodeViewRecordBuildID::kSignature;
WritableIoVec iov;
iov.iov_base = &cv;
iov.iov_len = offsetof(CodeViewRecordBuildID, build_id);
std::vector<WritableIoVec> iovecs(1, iov);
if (!build_id_.empty()) {
iov.iov_base = build_id_.data();
iov.iov_len = build_id_.size();
iovecs.push_back(iov);
}
return file_writer->WriteIoVec(&iovecs);
}
MinidumpModuleMiscDebugRecordWriter::MinidumpModuleMiscDebugRecordWriter()
: internal::MinidumpWritable(),
image_debug_misc_(),
data_(),
data_utf16_() {
}
data_utf16_() {}
MinidumpModuleMiscDebugRecordWriter::~MinidumpModuleMiscDebugRecordWriter() {
}
MinidumpModuleMiscDebugRecordWriter::~MinidumpModuleMiscDebugRecordWriter() {}
void MinidumpModuleMiscDebugRecordWriter::SetData(const std::string& data,
bool utf16) {
@ -203,8 +236,7 @@ MinidumpModuleWriter::MinidumpModuleWriter()
module_.VersionInfo.dwStrucVersion = VS_FFI_STRUCVERSION;
}
MinidumpModuleWriter::~MinidumpModuleWriter() {
}
MinidumpModuleWriter::~MinidumpModuleWriter() {}
void MinidumpModuleWriter::InitializeFromSnapshot(
const ModuleSnapshot* module_snapshot) {
@ -242,9 +274,21 @@ void MinidumpModuleWriter::InitializeFromSnapshot(
}
SetFileTypeAndSubtype(file_type, VFT2_UNKNOWN);
auto codeview_record =
auto build_id = module_snapshot->BuildID();
std::unique_ptr<MinidumpModuleCodeViewRecordWriter> codeview_record;
if (!build_id.empty()) {
auto cv_record_build_id =
std::make_unique<MinidumpModuleCodeViewRecordBuildIDWriter>();
cv_record_build_id->SetBuildID(build_id);
codeview_record = std::move(cv_record_build_id);
} else {
auto cv_record_pdb70 =
std::make_unique<MinidumpModuleCodeViewRecordPDB70Writer>();
codeview_record->InitializeFromSnapshot(module_snapshot);
cv_record_pdb70->InitializeFromSnapshot(module_snapshot);
codeview_record = std::move(cv_record_pdb70);
}
SetCodeViewRecord(std::move(codeview_record));
}
@ -372,11 +416,9 @@ bool MinidumpModuleWriter::WriteObject(FileWriterInterface* file_writer) {
}
MinidumpModuleListWriter::MinidumpModuleListWriter()
: MinidumpStreamWriter(), modules_(), module_list_base_() {
}
: MinidumpStreamWriter(), modules_(), module_list_base_() {}
MinidumpModuleListWriter::~MinidumpModuleListWriter() {
}
MinidumpModuleListWriter::~MinidumpModuleListWriter() {}
void MinidumpModuleListWriter::InitializeFromSnapshot(
const std::vector<const ModuleSnapshot*>& module_snapshots) {

View File

@ -88,7 +88,8 @@ class MinidumpModuleCodeViewRecordPDBLinkWriter
//! \brief The writer for a CodeViewRecordPDB20 object in a minidump file.
//!
//! Most users will want MinidumpModuleCodeViewRecordPDB70Writer instead.
//! Most users will want MinidumpModuleCodeViewRecordPDB70Writer or
//! MinidumpModuleCodeViewRecordBuildIDWriter instead.
class MinidumpModuleCodeViewRecordPDB20Writer final
: public internal::MinidumpModuleCodeViewRecordPDBLinkWriter<
CodeViewRecordPDB20> {
@ -136,6 +137,26 @@ class MinidumpModuleCodeViewRecordPDB70Writer final
DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCodeViewRecordPDB70Writer);
};
//! \brief The writer for a CodeViewRecordBuildID object in a minidump file.
class MinidumpModuleCodeViewRecordBuildIDWriter final
: public MinidumpModuleCodeViewRecordWriter {
public:
MinidumpModuleCodeViewRecordBuildIDWriter();
~MinidumpModuleCodeViewRecordBuildIDWriter() override;
//! \brief Sets the build ID used for symbol lookup.
void SetBuildID(const std::vector<uint8_t>& build_id);
private:
// MinidumpWritable:
size_t SizeOfObject() override;
bool WriteObject(FileWriterInterface* file_writer) override;
std::vector<uint8_t> build_id_;
DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCodeViewRecordBuildIDWriter);
};
//! \brief The writer for an IMAGE_DEBUG_MISC object in a minidump file.
//!
//! Most users will want MinidumpModuleCodeViewRecordPDB70Writer instead.

View File

@ -265,6 +265,61 @@ void ExpectModule(const MINIDUMP_MODULE* expected,
expected_debug_utf16));
}
// ExpectModuleWithBuildIDCv() is like ExpectModule( but expects the module to
// have a BuildID CodeView Record.
void ExpectModuleWithBuildIDCv(const MINIDUMP_MODULE* expected,
const MINIDUMP_MODULE* observed,
const std::string& file_contents,
const std::string& expected_module_name,
const std::vector<uint8_t>& expected_build_id) {
EXPECT_EQ(observed->BaseOfImage, expected->BaseOfImage);
EXPECT_EQ(observed->SizeOfImage, expected->SizeOfImage);
EXPECT_EQ(observed->CheckSum, expected->CheckSum);
EXPECT_EQ(observed->TimeDateStamp, expected->TimeDateStamp);
EXPECT_EQ(observed->VersionInfo.dwSignature,
implicit_cast<uint32_t>(VS_FFI_SIGNATURE));
EXPECT_EQ(observed->VersionInfo.dwStrucVersion,
implicit_cast<uint32_t>(VS_FFI_STRUCVERSION));
EXPECT_EQ(observed->VersionInfo.dwFileVersionMS,
expected->VersionInfo.dwFileVersionMS);
EXPECT_EQ(observed->VersionInfo.dwFileVersionLS,
expected->VersionInfo.dwFileVersionLS);
EXPECT_EQ(observed->VersionInfo.dwProductVersionMS,
expected->VersionInfo.dwProductVersionMS);
EXPECT_EQ(observed->VersionInfo.dwProductVersionLS,
expected->VersionInfo.dwProductVersionLS);
EXPECT_EQ(observed->VersionInfo.dwFileFlagsMask,
expected->VersionInfo.dwFileFlagsMask);
EXPECT_EQ(observed->VersionInfo.dwFileFlags,
expected->VersionInfo.dwFileFlags);
EXPECT_EQ(observed->VersionInfo.dwFileOS, expected->VersionInfo.dwFileOS);
EXPECT_EQ(observed->VersionInfo.dwFileType, expected->VersionInfo.dwFileType);
EXPECT_EQ(observed->VersionInfo.dwFileSubtype,
expected->VersionInfo.dwFileSubtype);
EXPECT_EQ(observed->VersionInfo.dwFileDateMS,
expected->VersionInfo.dwFileDateMS);
EXPECT_EQ(observed->VersionInfo.dwFileDateLS,
expected->VersionInfo.dwFileDateLS);
EXPECT_EQ(observed->Reserved0, 0u);
EXPECT_EQ(observed->Reserved1, 0u);
EXPECT_NE(observed->ModuleNameRva, 0u);
base::string16 observed_module_name_utf16 =
MinidumpStringAtRVAAsString(file_contents, observed->ModuleNameRva);
base::string16 expected_module_name_utf16 =
base::UTF8ToUTF16(expected_module_name);
EXPECT_EQ(observed_module_name_utf16, expected_module_name_utf16);
const CodeViewRecordBuildID* codeview_build_id_record =
MinidumpWritableAtLocationDescriptor<CodeViewRecordBuildID>(
file_contents, observed->CvRecord);
ASSERT_TRUE(codeview_build_id_record);
EXPECT_EQ(memcmp(expected_build_id.data(),
&codeview_build_id_record->build_id,
expected_build_id.size()),
0);
}
TEST(MinidumpModuleWriter, EmptyModule) {
MinidumpFileWriter minidump_file_writer;
auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();
@ -325,9 +380,22 @@ TEST(MinidumpModuleWriter, OneModule) {
constexpr uint32_t kFileType = VFT_DRV;
constexpr uint32_t kFileSubtype = VFT2_DRV_KEYBOARD;
static constexpr char kPDBName[] = "statical.pdb";
static constexpr uint8_t kPDBUUIDBytes[16] =
{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f};
static constexpr uint8_t kPDBUUIDBytes[16] = {0xfe,
0xdc,
0xba,
0x98,
0x76,
0x54,
0x32,
0x10,
0x08,
0x19,
0x2a,
0x3b,
0x4c,
0x5d,
0x6e,
0x7f};
UUID pdb_uuid;
pdb_uuid.InitializeFromBytes(kPDBUUIDBytes);
constexpr uint32_t kPDBAge = 1;
@ -471,6 +539,50 @@ TEST(MinidumpModuleWriter, OneModule_CodeViewUsesPDB20_MiscUsesUTF16) {
kDebugUTF16));
}
TEST(MinidumpModuleWriter, OneModule_CodeViewBuildID) {
// MinidumpModuleWriter.OneModule tested with a BuildID CodeView
MinidumpFileWriter minidump_file_writer;
auto module_list_writer = std::make_unique<MinidumpModuleListWriter>();
static constexpr char kModuleName[] = "dinosaur";
static constexpr char kBuildID[] =
"averylonghashcodeormaybeitsjustrandomnumbershardtosay";
std::vector<uint8_t> build_id_data(kBuildID, kBuildID + 53);
auto module_writer = std::make_unique<MinidumpModuleWriter>();
module_writer->SetName(kModuleName);
auto codeview_build_id_writer =
std::make_unique<MinidumpModuleCodeViewRecordBuildIDWriter>();
codeview_build_id_writer->SetBuildID(build_id_data);
module_writer->SetCodeViewRecord(std::move(codeview_build_id_writer));
module_list_writer->AddModule(std::move(module_writer));
ASSERT_TRUE(minidump_file_writer.AddStream(std::move(module_list_writer)));
StringFile string_file;
ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));
ASSERT_GT(string_file.string().size(),
sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));
const MINIDUMP_MODULE_LIST* module_list = nullptr;
ASSERT_NO_FATAL_FAILURE(
GetModuleListStream(string_file.string(), &module_list));
EXPECT_EQ(module_list->NumberOfModules, 1u);
MINIDUMP_MODULE expected = {};
ASSERT_NO_FATAL_FAILURE(ExpectModuleWithBuildIDCv(&expected,
&module_list->Modules[0],
string_file.string(),
kModuleName,
build_id_data));
}
TEST(MinidumpModuleWriter, ThreeModules) {
// As good exercise, this test uses three modules, one with a PDB 7.0 link as
// its CodeView record, one with no CodeView record, and one with a PDB 2.0
@ -482,9 +594,22 @@ TEST(MinidumpModuleWriter, ThreeModules) {
constexpr uint64_t kModuleBase0 = 0x100101000;
constexpr uint32_t kModuleSize0 = 0xf000;
static constexpr char kPDBName0[] = "main";
static constexpr uint8_t kPDBUUIDBytes0[16] =
{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
static constexpr uint8_t kPDBUUIDBytes0[16] = {0xaa,
0xbb,
0xcc,
0xdd,
0xee,
0xff,
0x00,
0x11,
0x22,
0x33,
0x44,
0x55,
0x66,
0x77,
0x88,
0x99};
UUID pdb_uuid_0;
pdb_uuid_0.InitializeFromBytes(kPDBUUIDBytes0);
constexpr uint32_t kPDBAge0 = 0;
@ -666,9 +791,22 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
expect_modules[0].VersionInfo.dwFileType = VFT_APP;
module_paths[0] = "/usr/bin/true";
module_pdbs[0] = "true";
static constexpr uint8_t kUUIDBytes0[16] =
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
static constexpr uint8_t kUUIDBytes0[16] = {0x00,
0x11,
0x22,
0x33,
0x44,
0x55,
0x66,
0x77,
0x88,
0x99,
0xaa,
0xbb,
0xcc,
0xdd,
0xee,
0xff};
uuids[0].InitializeFromBytes(kUUIDBytes0);
ages[0] = 10;
@ -682,9 +820,22 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
expect_modules[1].VersionInfo.dwFileType = VFT_DLL;
module_paths[1] = "/usr/lib/libSystem.B.dylib";
module_pdbs[1] = "libSystem.B.dylib.pdb";
static constexpr uint8_t kUUIDBytes1[16] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
static constexpr uint8_t kUUIDBytes1[16] = {0x00,
0x01,
0x02,
0x03,
0x04,
0x05,
0x06,
0x07,
0x08,
0x09,
0x0a,
0x0b,
0x0c,
0x0d,
0x0e,
0x0f};
uuids[1].InitializeFromBytes(kUUIDBytes1);
ages[1] = 20;
@ -698,9 +849,22 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
expect_modules[2].VersionInfo.dwFileType = VFT_UNKNOWN;
module_paths[2] = "/usr/lib/dyld";
module_pdbs[2] = "/usr/lib/dyld.pdb";
static constexpr uint8_t kUUIDBytes2[16] =
{0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0};
static constexpr uint8_t kUUIDBytes2[16] = {0xff,
0xfe,
0xfd,
0xfc,
0xfb,
0xfa,
0xf9,
0xf8,
0xf7,
0xf6,
0xf5,
0xf4,
0xf3,
0xf2,
0xf1,
0xf0};
uuids[2].InitializeFromBytes(kUUIDBytes2);
ages[2] = 30;

View File

@ -210,17 +210,13 @@ struct MinidumpMemoryInfoListTraits {
struct MinidumpModuleCrashpadInfoListTraits {
using ListType = MinidumpModuleCrashpadInfoList;
enum : size_t { kElementSize = sizeof(MinidumpModuleCrashpadInfoLink) };
static size_t ElementCount(const ListType* list) {
return list->count;
}
static size_t ElementCount(const ListType* list) { return list->count; }
};
struct MinidumpSimpleStringDictionaryListTraits {
using ListType = MinidumpSimpleStringDictionary;
enum : size_t { kElementSize = sizeof(MinidumpSimpleStringDictionaryEntry) };
static size_t ElementCount(const ListType* list) {
return list->count;
}
static size_t ElementCount(const ListType* list) { return list->count; }
};
struct MinidumpAnnotationListObjectsTraits {
@ -253,16 +249,18 @@ const typename T::ListType* MinidumpListAtLocationDescriptor(
} // namespace
template <>
const MINIDUMP_MEMORY_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_MEMORY_LIST>(const std::string& file_contents,
const MINIDUMP_MEMORY_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpListAtLocationDescriptor<MinidumpMemoryListTraits>(
file_contents, location);
}
template <>
const MINIDUMP_MODULE_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_MODULE_LIST>(const std::string& file_contents,
const MINIDUMP_MODULE_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MODULE_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpListAtLocationDescriptor<MinidumpModuleListTraits>(
file_contents, location);
@ -278,24 +276,27 @@ MinidumpWritableAtLocationDescriptor<MINIDUMP_UNLOADED_MODULE_LIST>(
}
template <>
const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_THREAD_LIST>(const std::string& file_contents,
const MINIDUMP_THREAD_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_THREAD_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpListAtLocationDescriptor<MinidumpThreadListTraits>(
file_contents, location);
}
template <>
const MINIDUMP_HANDLE_DATA_STREAM* MinidumpWritableAtLocationDescriptor<
MINIDUMP_HANDLE_DATA_STREAM>(const std::string& file_contents,
const MINIDUMP_HANDLE_DATA_STREAM*
MinidumpWritableAtLocationDescriptor<MINIDUMP_HANDLE_DATA_STREAM>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpListAtLocationDescriptor<MinidumpHandleDataStreamTraits>(
file_contents, location);
}
template <>
const MINIDUMP_MEMORY_INFO_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_MEMORY_INFO_LIST>(const std::string& file_contents,
const MINIDUMP_MEMORY_INFO_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_INFO_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpListAtLocationDescriptor<MinidumpMemoryInfoListTraits>(
file_contents, location);
@ -357,28 +358,51 @@ const T* MinidumpCVPDBAtLocationDescriptor(
} // namespace
template <>
const CodeViewRecordPDB20* MinidumpWritableAtLocationDescriptor<
CodeViewRecordPDB20>(const std::string& file_contents,
const CodeViewRecordPDB20*
MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB20>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpCVPDBAtLocationDescriptor<CodeViewRecordPDB20>(file_contents,
location);
}
template <>
const CodeViewRecordPDB70* MinidumpWritableAtLocationDescriptor<
CodeViewRecordPDB70>(const std::string& file_contents,
const CodeViewRecordPDB70*
MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB70>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
return MinidumpCVPDBAtLocationDescriptor<CodeViewRecordPDB70>(file_contents,
location);
}
TestUInt32MinidumpWritable::TestUInt32MinidumpWritable(uint32_t value)
: MinidumpWritable(),
value_(value) {
template <>
const CodeViewRecordBuildID*
MinidumpWritableAtLocationDescriptor<CodeViewRecordBuildID>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
const CodeViewRecordBuildID* cv =
reinterpret_cast<const CodeViewRecordBuildID*>(
MinidumpWritableAtLocationDescriptorInternal(
file_contents,
location,
offsetof(CodeViewRecordBuildID, build_id),
true));
if (!cv) {
return nullptr;
}
if (cv->signature != CodeViewRecordBuildID::kSignature) {
return nullptr;
}
return cv;
}
TestUInt32MinidumpWritable::~TestUInt32MinidumpWritable() {
}
TestUInt32MinidumpWritable::TestUInt32MinidumpWritable(uint32_t value)
: MinidumpWritable(), value_(value) {}
TestUInt32MinidumpWritable::~TestUInt32MinidumpWritable() {}
size_t TestUInt32MinidumpWritable::SizeOfObject() {
return sizeof(value_);

View File

@ -104,6 +104,7 @@ MINIDUMP_ALLOW_OVERSIZED_DATA(IMAGE_DEBUG_MISC);
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_STRING);
MINIDUMP_ALLOW_OVERSIZED_DATA(CodeViewRecordPDB20);
MINIDUMP_ALLOW_OVERSIZED_DATA(CodeViewRecordPDB70);
MINIDUMP_ALLOW_OVERSIZED_DATA(CodeViewRecordBuildID);
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpUTF8String);
// minidump_file_writer_test accesses its variable-sized test streams via a
@ -179,13 +180,15 @@ const MINIDUMP_HEADER* MinidumpWritableAtLocationDescriptor<MINIDUMP_HEADER>(
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const MINIDUMP_MEMORY_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_MEMORY_LIST>(const std::string& file_contents,
const MINIDUMP_MEMORY_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const MINIDUMP_MODULE_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_MODULE_LIST>(const std::string& file_contents,
const MINIDUMP_MODULE_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MODULE_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
@ -195,28 +198,39 @@ MinidumpWritableAtLocationDescriptor<MINIDUMP_UNLOADED_MODULE_LIST>(
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_THREAD_LIST>(const std::string& file_contents,
const MINIDUMP_THREAD_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_THREAD_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const MINIDUMP_HANDLE_DATA_STREAM* MinidumpWritableAtLocationDescriptor<
MINIDUMP_HANDLE_DATA_STREAM>(const std::string& file_contents,
const MINIDUMP_HANDLE_DATA_STREAM*
MinidumpWritableAtLocationDescriptor<MINIDUMP_HANDLE_DATA_STREAM>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const MINIDUMP_MEMORY_INFO_LIST* MinidumpWritableAtLocationDescriptor<
MINIDUMP_MEMORY_INFO_LIST>(const std::string& file_contents,
const MINIDUMP_MEMORY_INFO_LIST*
MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_INFO_LIST>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const CodeViewRecordPDB20* MinidumpWritableAtLocationDescriptor<
CodeViewRecordPDB20>(const std::string& file_contents,
const CodeViewRecordPDB20*
MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB20>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const CodeViewRecordPDB70* MinidumpWritableAtLocationDescriptor<
CodeViewRecordPDB70>(const std::string& file_contents,
const CodeViewRecordPDB70*
MinidumpWritableAtLocationDescriptor<CodeViewRecordPDB70>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>
const CodeViewRecordBuildID*
MinidumpWritableAtLocationDescriptor<CodeViewRecordBuildID>(
const std::string& file_contents,
const MINIDUMP_LOCATION_DESCRIPTOR& location);
template <>

View File

@ -150,13 +150,10 @@ void ModuleSnapshotElf::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
*age = 0;
std::unique_ptr<ElfImageReader::NoteReader> notes =
elf_reader_->NotesWithNameAndType(ELF_NOTE_GNU, NT_GNU_BUILD_ID, 64);
std::string desc;
VMAddress desc_addr;
notes->NextNote(nullptr, nullptr, &desc, &desc_addr);
desc.insert(desc.end(), 16 - std::min(desc.size(), size_t{16}), '\0');
uuid->InitializeFromBytes(reinterpret_cast<const uint8_t*>(&desc[0]));
auto build_id = BuildID();
build_id.insert(
build_id.end(), 16 - std::min(build_id.size(), size_t{16}), '\0');
uuid->InitializeFromBytes(build_id.data());
// TODO(scottmg): https://crashpad.chromium.org/bug/229. These are
// endian-swapped to match FileID::ConvertIdentifierToUUIDString() in
@ -171,6 +168,21 @@ std::string ModuleSnapshotElf::DebugFileName() const {
return base::FilePath(Name()).BaseName().value();
}
std::vector<uint8_t> ModuleSnapshotElf::BuildID() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
std::unique_ptr<ElfImageReader::NoteReader> notes =
elf_reader_->NotesWithNameAndType(ELF_NOTE_GNU, NT_GNU_BUILD_ID, 64);
std::string desc;
VMAddress desc_addr;
notes->NextNote(nullptr, nullptr, &desc, &desc_addr);
std::vector<uint8_t> build_id;
build_id.reserve(desc.size());
std::copy(desc.begin(), desc.end(), std::back_inserter(build_id));
return build_id;
}
std::vector<std::string> ModuleSnapshotElf::AnnotationsVector() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return std::vector<std::string>();

View File

@ -77,6 +77,7 @@ class ModuleSnapshotElf final : public ModuleSnapshot {
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<uint8_t> BuildID() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;

View File

@ -14,8 +14,8 @@
#include "snapshot/mac/module_snapshot_mac.h"
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <mach/mach.h>
#include "base/files/file_path.h"
#include "base/strings/stringprintf.h"
@ -34,11 +34,9 @@ ModuleSnapshotMac::ModuleSnapshotMac()
timestamp_(0),
mach_o_image_reader_(nullptr),
process_reader_(nullptr),
initialized_() {
}
initialized_() {}
ModuleSnapshotMac::~ModuleSnapshotMac() {
}
ModuleSnapshotMac::~ModuleSnapshotMac() {}
bool ModuleSnapshotMac::Initialize(
ProcessReaderMac* process_reader,
@ -170,6 +168,11 @@ std::string ModuleSnapshotMac::DebugFileName() const {
return base::FilePath(Name()).BaseName().value();
}
std::vector<uint8_t> ModuleSnapshotMac::BuildID() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return std::vector<uint8_t>();
}
std::vector<std::string> ModuleSnapshotMac::AnnotationsVector() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
MachOImageAnnotationsReader annotations_reader(

View File

@ -77,6 +77,7 @@ class ModuleSnapshotMac final : public ModuleSnapshot {
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<uint8_t> BuildID() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;

View File

@ -14,13 +14,15 @@
#include "snapshot/minidump/module_snapshot_minidump.h"
#include <stddef.h>
#include <string.h>
#include "base/logging.h"
#include "minidump/minidump_extensions.h"
#include "snapshot/minidump/minidump_annotation_reader.h"
#include "snapshot/minidump/minidump_string_reader.h"
#include "snapshot/minidump/minidump_simple_string_dictionary_reader.h"
#include "snapshot/minidump/minidump_string_list_reader.h"
#include "snapshot/minidump/minidump_string_reader.h"
#include "util/misc/pdb_structures.h"
namespace crashpad {
@ -33,13 +35,13 @@ ModuleSnapshotMinidump::ModuleSnapshotMinidump()
annotations_simple_map_(),
annotation_objects_(),
uuid_(),
build_id_(),
name_(),
debug_file_name_(),
age_(0),
initialized_() {
}
initialized_() {}
ModuleSnapshotMinidump::~ModuleSnapshotMinidump() {
}
ModuleSnapshotMinidump::~ModuleSnapshotMinidump() {}
bool ModuleSnapshotMinidump::Initialize(
FileReaderInterface* file_reader,
@ -63,31 +65,66 @@ bool ModuleSnapshotMinidump::Initialize(
ReadMinidumpUTF16String(file_reader, minidump_module_.ModuleNameRva, &name_);
if (minidump_module_.CvRecord.Rva != 0) {
CodeViewRecordPDB70 cv;
if (minidump_module_.CvRecord.Rva != 0 &&
!InitializeModuleCodeView(file_reader)) {
return false;
}
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
bool ModuleSnapshotMinidump::InitializeModuleCodeView(
FileReaderInterface* file_reader) {
uint32_t signature;
DCHECK_NE(minidump_module_.CvRecord.Rva, 0u);
if (minidump_module_.CvRecord.DataSize < sizeof(signature)) {
LOG(ERROR) << "CodeView record in module too small to contain signature";
return false;
}
if (!file_reader->SeekSet(minidump_module_.CvRecord.Rva)) {
return false;
}
if (!file_reader->ReadExactly(&cv, sizeof(cv))) {
std::vector<uint8_t> cv_record;
cv_record.resize(minidump_module_.CvRecord.DataSize);
if (!file_reader->ReadExactly(cv_record.data(), cv_record.size())) {
return false;
}
if (cv.signature == 'SDSR') {
age_ = cv.age;
uuid_ = cv.uuid;
} else if (cv.signature != '01BN') {
signature = *reinterpret_cast<uint32_t*>(cv_record.data());
if (signature == CodeViewRecordPDB70::kSignature) {
if (cv_record.size() < offsetof(CodeViewRecordPDB70, pdb_name)) {
LOG(ERROR) << "CodeView record in module marked as PDB70 but too small";
return false;
}
auto cv_record_pdb70 =
reinterpret_cast<CodeViewRecordPDB70*>(cv_record.data());
age_ = cv_record_pdb70->age;
uuid_ = cv_record_pdb70->uuid;
std::copy(cv_record.begin() + offsetof(CodeViewRecordPDB70, pdb_name),
cv_record.end(),
std::back_inserter(debug_file_name_));
return true;
}
if (signature == CodeViewRecordBuildID::kSignature) {
std::copy(cv_record.begin() + offsetof(CodeViewRecordBuildID, build_id),
cv_record.end(),
std::back_inserter(build_id_));
return true;
}
LOG(ERROR) << "Bad CodeView signature in module";
return false;
} else {
LOG(ERROR) << "NB10 not supported";
return false;
}
}
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
std::string ModuleSnapshotMinidump::Name() const {
@ -155,8 +192,12 @@ void ModuleSnapshotMinidump::UUIDAndAge(crashpad::UUID* uuid,
std::string ModuleSnapshotMinidump::DebugFileName() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return std::string();
return debug_file_name_;
}
std::vector<uint8_t> ModuleSnapshotMinidump::BuildID() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return build_id_;
}
std::vector<std::string> ModuleSnapshotMinidump::AnnotationsVector() const {

View File

@ -75,6 +75,7 @@ class ModuleSnapshotMinidump final : public ModuleSnapshot {
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<uint8_t> BuildID() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;
@ -88,12 +89,18 @@ class ModuleSnapshotMinidump final : public ModuleSnapshot {
const MINIDUMP_LOCATION_DESCRIPTOR*
minidump_module_crashpad_info_location);
// Initializes data from the CodeView record, which usually points toward
// debug symbols.
bool InitializeModuleCodeView(FileReaderInterface* file_reader);
MINIDUMP_MODULE minidump_module_;
std::vector<std::string> annotations_vector_;
std::map<std::string, std::string> annotations_simple_map_;
std::vector<AnnotationSnapshot> annotation_objects_;
UUID uuid_;
std::vector<uint8_t> build_id_;
std::string name_;
std::string debug_file_name_;
uint32_t age_;
InitializationStateDcheck initialized_;

View File

@ -331,16 +331,28 @@ TEST(ProcessSnapshotMinidump, Modules) {
EXPECT_TRUE(string_file.Write(&name16[0], size));
}
CodeViewRecordPDB70 cv;
cv.signature = CodeViewRecordPDB70::kSignature;
cv.age = 7;
cv.uuid.InitializeFromString("00112233-4455-6677-8899-aabbccddeeff");
cv.pdb_name[0] = '\0';
CodeViewRecordPDB70 pdb70_cv;
pdb70_cv.signature = CodeViewRecordPDB70::kSignature;
pdb70_cv.age = 7;
pdb70_cv.uuid.InitializeFromString("00112233-4455-6677-8899-aabbccddeeff");
pdb70_cv.pdb_name[0] = '\0';
minidump_module.CvRecord.Rva = static_cast<RVA>(string_file.SeekGet());
minidump_module.CvRecord.DataSize = sizeof(cv);
auto pdb70_loc = static_cast<RVA>(string_file.SeekGet());
auto pdb70_size = sizeof(pdb70_cv);
EXPECT_TRUE(string_file.Write(&cv, sizeof(cv)));
EXPECT_TRUE(string_file.Write(&pdb70_cv, sizeof(pdb70_cv)));
CodeViewRecordBuildID build_id_cv;
build_id_cv.signature = CodeViewRecordBuildID::kSignature;
auto build_id_cv_loc = static_cast<RVA>(string_file.SeekGet());
EXPECT_TRUE(string_file.Write(&build_id_cv,
offsetof(CodeViewRecordBuildID, build_id)));
EXPECT_TRUE(string_file.Write("atestbuildidbecausewhynot", 25));
auto build_id_cv_size =
static_cast<size_t>(string_file.SeekGet() - build_id_cv_loc);
MINIDUMP_DIRECTORY minidump_module_list_directory = {};
minidump_module_list_directory.StreamType = kMinidumpStreamTypeModuleList;
@ -355,6 +367,15 @@ TEST(ProcessSnapshotMinidump, Modules) {
for (uint32_t minidump_module_index = 0;
minidump_module_index < minidump_module_count;
++minidump_module_index) {
if (minidump_module_index % 2) {
minidump_module.CvRecord.Rva = pdb70_loc;
minidump_module.CvRecord.DataSize = static_cast<uint32_t>(pdb70_size);
} else {
minidump_module.CvRecord.Rva = build_id_cv_loc;
minidump_module.CvRecord.DataSize =
static_cast<uint32_t>(build_id_cv_size);
}
minidump_module.ModuleNameRva = name_rvas[minidump_module_index];
EXPECT_TRUE(string_file.Write(&minidump_module, sizeof(minidump_module)));
minidump_module.TimeDateStamp++;
@ -479,12 +500,19 @@ TEST(ProcessSnapshotMinidump, Modules) {
EXPECT_EQ(modules[i]->GetModuleType(),
ModuleSnapshot::kModuleTypeExecutable);
if (i % 2) {
uint32_t age;
UUID uuid;
modules[i]->UUIDAndAge(&uuid, &age);
EXPECT_EQ(uuid.ToString(), "00112233-4455-6677-8899-aabbccddeeff");
EXPECT_EQ(age, 7U);
} else {
auto build_id = modules[i]->BuildID();
std::string build_id_text(build_id.data(),
build_id.data() + build_id.size());
EXPECT_EQ(build_id_text, "atestbuildidbecausewhynot");
}
}
auto annotations_simple_map = modules[0]->AnnotationsSimpleMap();
@ -626,8 +654,8 @@ TEST(ProcessSnapshotMinidump, System) {
minidump_system_info_directory.Location.Rva =
static_cast<RVA>(string_file.SeekGet());
ASSERT_TRUE(string_file.Write(&minidump_system_info,
sizeof(minidump_system_info)));
ASSERT_TRUE(
string_file.Write(&minidump_system_info, sizeof(minidump_system_info)));
header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet());
ASSERT_TRUE(string_file.Write(&minidump_system_info_directory,
@ -680,8 +708,8 @@ TEST(ProcessSnapshotMinidump, ThreadContextARM64) {
minidump_system_info_directory.Location.Rva =
static_cast<RVA>(string_file.SeekGet());
ASSERT_TRUE(string_file.Write(&minidump_system_info,
sizeof(minidump_system_info)));
ASSERT_TRUE(
string_file.Write(&minidump_system_info, sizeof(minidump_system_info)));
MINIDUMP_THREAD minidump_thread = {};
uint32_t minidump_thread_count = 1;
@ -801,8 +829,8 @@ TEST(ProcessSnapshotMinidump, ThreadContextX86_64) {
minidump_system_info_directory.Location.Rva =
static_cast<RVA>(string_file.SeekGet());
ASSERT_TRUE(string_file.Write(&minidump_system_info,
sizeof(minidump_system_info)));
ASSERT_TRUE(
string_file.Write(&minidump_system_info, sizeof(minidump_system_info)));
MINIDUMP_THREAD minidump_thread = {};
uint32_t minidump_thread_count = 1;
@ -1045,10 +1073,14 @@ TEST(ProcessSnapshotMinidump, MemoryMap) {
std::vector<const MemoryMapRegionSnapshot*> map =
process_snapshot.MemoryMap();
ASSERT_EQ(map.size(), minidump_memory_info_count);
EXPECT_EQ(memcmp(&map[0]->AsMinidumpMemoryInfo(), &minidump_memory_info_1,
sizeof(minidump_memory_info_1)), 0);
EXPECT_EQ(memcmp(&map[1]->AsMinidumpMemoryInfo(), &minidump_memory_info_2,
sizeof(minidump_memory_info_2)), 0);
EXPECT_EQ(memcmp(&map[0]->AsMinidumpMemoryInfo(),
&minidump_memory_info_1,
sizeof(minidump_memory_info_1)),
0);
EXPECT_EQ(memcmp(&map[1]->AsMinidumpMemoryInfo(),
&minidump_memory_info_2,
sizeof(minidump_memory_info_2)),
0);
}
TEST(ProcessSnapshotMinidump, Stacks) {
@ -1063,9 +1095,21 @@ TEST(ProcessSnapshotMinidump, Stacks) {
minidump_thread.ThreadId = 42;
minidump_thread.Stack.StartOfMemoryRange = 0xbeefd00d;
std::vector<uint8_t> minidump_stack = {
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
std::vector<uint8_t> minidump_stack = {'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
minidump_thread.Stack.Memory.DataSize =
base::checked_cast<uint32_t>(minidump_stack.size());

View File

@ -146,6 +146,7 @@ class ModuleSnapshot {
//! Windows with incremental linking. On other platforms \a age will always be
//! `0`.
//!
//! \sa BuildID()
//! \sa DebugFileName()
virtual void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const = 0;
@ -159,6 +160,20 @@ class ModuleSnapshot {
//! \sa UUIDAndAge()
virtual std::string DebugFileName() const = 0;
//! \brief Returns the modules build ID.
//!
//! On ELF platforms, the build ID is a variable-length byte stream that
//! identifies a library uniquely, and is usually used to look up its debug
//! symbols when stored separately. This will return an empty vector if it is
//! unsupported.
//!
//! BuildID() and UUIDAndAge() are never available in the same place. When
//! UUIDAndAge() is unavailable, it will be filled out with the contents of
//! BuildID() (either 0-padded or truncated) and age will be zero.
//!
//! \sa UUIDAndAge()
virtual std::vector<uint8_t> BuildID() const = 0;
//! \brief Returns string annotations recorded in the module.
//!
//! This method retrieves annotations recorded in a module. These annotations

View File

@ -81,6 +81,10 @@ std::string ModuleSnapshotSanitized::DebugFileName() const {
return snapshot_->DebugFileName();
}
std::vector<uint8_t> ModuleSnapshotSanitized::BuildID() const {
return snapshot_->BuildID();
}
std::vector<std::string> ModuleSnapshotSanitized::AnnotationsVector() const {
// TODO(jperaza): If/when AnnotationsVector() begins to be used, determine
// whether and how the content should be sanitized.

View File

@ -56,6 +56,7 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot {
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<uint8_t> BuildID() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;

View File

@ -30,11 +30,9 @@ TestModuleSnapshot::TestModuleSnapshot()
debug_file_name_(),
annotations_vector_(),
annotations_simple_map_(),
extra_memory_ranges_() {
}
extra_memory_ranges_() {}
TestModuleSnapshot::~TestModuleSnapshot() {
}
TestModuleSnapshot::~TestModuleSnapshot() {}
std::string TestModuleSnapshot::Name() const {
return name_;
@ -85,6 +83,10 @@ std::string TestModuleSnapshot::DebugFileName() const {
return debug_file_name_;
}
std::vector<uint8_t> TestModuleSnapshot::BuildID() const {
return build_id_;
}
std::vector<std::string> TestModuleSnapshot::AnnotationsVector() const {
return annotations_vector_;
}

View File

@ -64,6 +64,9 @@ class TestModuleSnapshot final : public ModuleSnapshot {
uuid_ = uuid;
age_ = age;
}
void SetBuildID(const std::vector<uint8_t>& build_id) {
build_id_ = build_id;
}
void SetDebugFileName(const std::string& debug_file_name) {
debug_file_name_ = debug_file_name;
}
@ -101,6 +104,7 @@ class TestModuleSnapshot final : public ModuleSnapshot {
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<uint8_t> BuildID() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;
@ -117,6 +121,7 @@ class TestModuleSnapshot final : public ModuleSnapshot {
ModuleType module_type_;
uint32_t age_;
crashpad::UUID uuid_;
std::vector<uint8_t> build_id_;
std::string debug_file_name_;
std::vector<std::string> annotations_vector_;
std::map<std::string, std::string> annotations_simple_map_;

View File

@ -44,8 +44,7 @@ ModuleSnapshotWin::ModuleSnapshotWin()
age_(0),
initialized_() {}
ModuleSnapshotWin::~ModuleSnapshotWin() {
}
ModuleSnapshotWin::~ModuleSnapshotWin() {}
bool ModuleSnapshotWin::Initialize(
ProcessReaderWin* process_reader,
@ -195,6 +194,11 @@ std::string ModuleSnapshotWin::DebugFileName() const {
return pdb_name_;
}
std::vector<uint8_t> ModuleSnapshotWin::BuildID() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return std::vector<uint8_t>();
}
std::vector<std::string> ModuleSnapshotWin::AnnotationsVector() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// These correspond to system-logged things on Mac. We don't currently track

View File

@ -84,6 +84,7 @@ class ModuleSnapshotWin final : public ModuleSnapshot {
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<uint8_t> BuildID() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;

View File

@ -18,5 +18,6 @@ namespace crashpad {
const uint32_t CodeViewRecordPDB20::kSignature;
const uint32_t CodeViewRecordPDB70::kSignature;
const uint32_t CodeViewRecordBuildID::kSignature;
} // namespace crashpad

View File

@ -90,12 +90,7 @@ struct CodeViewRecordPDB70 {
// UUID has a constructor, which makes it non-POD, which makes this structure
// non-POD. In order for the default constructor to zero-initialize other
// members, an explicit constructor must be provided.
CodeViewRecordPDB70()
: signature(),
uuid(),
age(),
pdb_name() {
}
CodeViewRecordPDB70() : signature(), uuid(), age(), pdb_name() {}
//! \brief The magic number identifying this structure version, stored in
//! #signature.
@ -127,6 +122,27 @@ struct CodeViewRecordPDB70 {
uint8_t pdb_name[1];
};
//! \brief A CodeView record containing an ELF build-id.
//!
//! This identifier comes from the ELF section `NT_GNU_BUILD_ID`.
struct CodeViewRecordBuildID {
//! \brief The magic number identifying this structure version, stored in
//! #signature.
//!
//! In a hex dump, this will appear as “LEpB” when produced by a little-endian
//! machine.
static const uint32_t kSignature = 'BpEL';
//! \brief The magic number identifying this structure version, the value of
//! #kSignature.
uint32_t signature;
//! \brief The build ID for this object.
//!
//! This usually comes from `NT_GNU_BUILD_ID` on ELF objects.
uint8_t build_id[1];
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_MISC_PDB_STRUCTURES_H_