win: Plumb module PDB name through snapshot

R=mark@chromium.org
BUG=chromium:546288

Review URL: https://codereview.chromium.org/1415543003 .
This commit is contained in:
Scott Graham 2015-10-29 10:48:23 -07:00
parent ad9887ee0d
commit 3ee9d891d9
11 changed files with 69 additions and 22 deletions

View File

@ -106,15 +106,7 @@ void MinidumpModuleCodeViewRecordPDB70Writer::InitializeFromSnapshot(
const ModuleSnapshot* module_snapshot) {
DCHECK_EQ(state(), kStateMutable);
std::string name = module_snapshot->Name();
std::string leaf_name;
size_t last_slash = name.find_last_of('/');
if (last_slash != std::string::npos) {
leaf_name = name.substr(last_slash + 1);
} else {
leaf_name = name;
}
SetPDBName(leaf_name);
SetPDBName(module_snapshot->DebugFileName());
UUID uuid;
uint32_t age;

View File

@ -614,6 +614,7 @@ void InitializeTestModuleSnapshotFromMinidumpModule(
TestModuleSnapshot* module_snapshot,
const MINIDUMP_MODULE& minidump_module,
const std::string& name,
const std::string& pdb_name,
const crashpad::UUID& uuid,
uint32_t age) {
module_snapshot->SetName(name);
@ -647,12 +648,14 @@ void InitializeTestModuleSnapshotFromMinidumpModule(
module_snapshot->SetModuleType(module_type);
module_snapshot->SetUUIDAndAge(uuid, age);
module_snapshot->SetDebugFileName(pdb_name);
}
TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
MINIDUMP_MODULE expect_modules[3] = {};
const char* module_paths[arraysize(expect_modules)] = {};
const char* module_names[arraysize(expect_modules)] = {};
const char* module_pdbs[arraysize(expect_modules)] = {};
UUID uuids[arraysize(expect_modules)] = {};
uint32_t ages[arraysize(expect_modules)] = {};
@ -666,6 +669,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
expect_modules[0].VersionInfo.dwFileType = VFT_APP;
module_paths[0] = "/usr/bin/true";
module_names[0] = "true";
module_pdbs[0] = "true";
const uint8_t kUUIDBytes0[16] =
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
@ -682,6 +686,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
expect_modules[1].VersionInfo.dwFileType = VFT_DLL;
module_paths[1] = "/usr/lib/libSystem.B.dylib";
module_names[1] = "libSystem.B.dylib";
module_pdbs[1] = "libSystem.B.dylib.pdb";
const uint8_t kUUIDBytes1[16] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
@ -698,6 +703,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
expect_modules[2].VersionInfo.dwFileType = VFT_UNKNOWN;
module_paths[2] = "/usr/lib/dyld";
module_names[2] = "dyld";
module_pdbs[2] = "/usr/lib/dyld.pdb";
const uint8_t kUUIDBytes2[16] =
{0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0};
@ -712,6 +718,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
InitializeTestModuleSnapshotFromMinidumpModule(module_snapshot,
expect_modules[index],
module_paths[index],
module_pdbs[index],
uuids[index],
ages[index]);
module_snapshots.push_back(module_snapshot);
@ -738,7 +745,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) {
&module_list->Modules[index],
string_file.string(),
module_paths[index],
module_names[index],
module_pdbs[index],
&uuids[index],
0,
ages[index],

View File

@ -17,6 +17,7 @@
#include <mach/mach.h>
#include <mach-o/loader.h>
#include "base/files/file_path.h"
#include "base/strings/stringprintf.h"
#include "snapshot/mac/mach_o_image_annotations_reader.h"
#include "snapshot/mac/mach_o_image_reader.h"
@ -156,6 +157,11 @@ void ModuleSnapshotMac::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
*age = 0;
}
std::string ModuleSnapshotMac::DebugFileName() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return base::FilePath(Name()).BaseName().value();
}
std::vector<std::string> ModuleSnapshotMac::AnnotationsVector() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
MachOImageAnnotationsReader annotations_reader(

View File

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

View File

@ -118,6 +118,12 @@ void ModuleSnapshotMinidump::UUIDAndAge(crashpad::UUID* uuid,
*age = 0;
}
std::string ModuleSnapshotMinidump::DebugFileName() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://code.google.com/p/crashpad/issues/detail?id=10
return std::string();
}
std::vector<std::string> ModuleSnapshotMinidump::AnnotationsVector() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return annotations_vector_;

View File

@ -73,6 +73,7 @@ class ModuleSnapshotMinidump final : public ModuleSnapshot {
uint16_t* version_3) const override;
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;

View File

@ -118,8 +118,20 @@ class ModuleSnapshot {
//! \a age is the number of times the UUID has been reused. This occurs on
//! Windows with incremental linking. On other platforms \a age will always be
//! `0`.
//!
//! \sa DebugFileName()
virtual void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const = 0;
//! \brief Returns the modules debug file info name.
//!
//! On Windows, this references the PDB file, which contains symbol
//! information held separately from the module itself. On other platforms,
//! this is normally just be the basename of the module, because the debug
//! info files name is not relevant even in split-debug scenarios.
//!
//! \sa UUIDAndAge()
virtual std::string DebugFileName() const = 0;
//! \brief Returns string annotations recorded in the module.
//!
//! This method retrieves annotations recorded in a module. These annotations

View File

@ -27,6 +27,7 @@ TestModuleSnapshot::TestModuleSnapshot()
module_type_(kModuleTypeUnknown),
age_(0),
uuid_(),
debug_file_name_(),
annotations_vector_(),
annotations_simple_map_() {
}
@ -79,6 +80,10 @@ void TestModuleSnapshot::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
*age = age_;
}
std::string TestModuleSnapshot::DebugFileName() const {
return debug_file_name_;
}
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 SetDebugFileName(const std::string& debug_file_name) {
debug_file_name_ = debug_file_name;
}
void SetAnnotationsVector(
const std::vector<std::string>& annotations_vector) {
annotations_vector_ = annotations_vector;
@ -89,6 +92,7 @@ class TestModuleSnapshot final : public ModuleSnapshot {
uint16_t* version_3) const override;
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
@ -102,6 +106,7 @@ class TestModuleSnapshot final : public ModuleSnapshot {
ModuleType module_type_;
uint32_t age_;
crashpad::UUID uuid_;
std::string debug_file_name_;
std::vector<std::string> annotations_vector_;
std::map<std::string, std::string> annotations_simple_map_;

View File

@ -27,8 +27,12 @@ namespace internal {
ModuleSnapshotWin::ModuleSnapshotWin()
: ModuleSnapshot(),
name_(),
timestamp_(0),
pdb_name_(),
uuid_(),
pe_image_reader_(),
process_reader_(nullptr),
timestamp_(0),
age_(0),
initialized_() {
}
@ -51,6 +55,13 @@ bool ModuleSnapshotWin::Initialize(
return false;
}
DWORD age_dword;
if (pe_image_reader_->DebugDirectoryInformation(
&uuid_, &age_dword, &pdb_name_)) {
static_assert(sizeof(DWORD) == sizeof(uint32_t), "unexpected age size");
age_ = age_dword;
}
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
@ -137,16 +148,13 @@ ModuleSnapshot::ModuleType ModuleSnapshotWin::GetModuleType() const {
void ModuleSnapshotWin::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// TODO(scottmg): Consider passing pdbname through to snapshot.
std::string pdbname;
DWORD age_dword;
if (!pe_image_reader_->DebugDirectoryInformation(
uuid, &age_dword, &pdbname)) {
*uuid = crashpad::UUID();
*age = 0;
}
static_assert(sizeof(DWORD) == sizeof(uint32_t), "unexpected age size");
*age = age_dword;
*uuid = uuid_;
*age = age_;
}
std::string ModuleSnapshotWin::DebugFileName() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return pdb_name_;
}
std::vector<std::string> ModuleSnapshotWin::AnnotationsVector() const {

View File

@ -81,6 +81,7 @@ class ModuleSnapshotWin final : public ModuleSnapshot {
uint16_t* version_3) const override;
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
@ -89,9 +90,12 @@ class ModuleSnapshotWin final : public ModuleSnapshot {
void GetCrashpadOptionsInternal(CrashpadInfoClientOptions* options);
std::wstring name_;
time_t timestamp_;
std::string pdb_name_;
UUID uuid_;
scoped_ptr<PEImageReader> pe_image_reader_;
ProcessReaderWin* process_reader_; // weak
time_t timestamp_;
uint32_t age_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotWin);