| Index: third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
|
| diff --git a/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
|
| index 535c9a7374b5641e68e0890cbcaaddfb8f0ca512..9c72855f31eb0e02acafe2f785a8ed99b8193ea2 100644
|
| --- a/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
|
| +++ b/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
|
| @@ -21,6 +21,7 @@
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "snapshot/win/memory_snapshot_win.h"
|
| #include "snapshot/win/module_snapshot_win.h"
|
| +#include "util/win/nt_internals.h"
|
| #include "util/win/registration_protocol_win.h"
|
| #include "util/win/time.h"
|
|
|
| @@ -67,6 +68,7 @@ bool ProcessSnapshotWin::Initialize(
|
| }
|
|
|
| InitializeModules();
|
| + InitializeUnloadedModules();
|
|
|
| GetCrashpadOptionsInternal(&options_);
|
|
|
| @@ -177,6 +179,12 @@ std::vector<const ModuleSnapshot*> ProcessSnapshotWin::Modules() const {
|
| return modules;
|
| }
|
|
|
| +std::vector<UnloadedModuleSnapshot> ProcessSnapshotWin::UnloadedModules()
|
| + const {
|
| + INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
| + return unloaded_modules_;
|
| +}
|
| +
|
| const ExceptionSnapshot* ProcessSnapshotWin::Exception() const {
|
| return exception_.get();
|
| }
|
| @@ -242,6 +250,53 @@ void ProcessSnapshotWin::InitializeModules() {
|
| }
|
| }
|
|
|
| +void ProcessSnapshotWin::InitializeUnloadedModules() {
|
| + // As documented by https://msdn.microsoft.com/en-us/library/cc678403.aspx
|
| + // we can retrieve the location for our unload events, and use that address in
|
| + // the target process. Unfortunately, this of course only works for
|
| + // 64-reading-64 and 32-reading-32, so at the moment, we simply do not
|
| + // retrieve unloaded modules for 64-reading-32. See
|
| + // https://crashpad.chromium.org/bug/89.
|
| +
|
| +#if defined(ARCH_CPU_X86_64)
|
| + if (!process_reader_.Is64Bit()) {
|
| + LOG(ERROR)
|
| + << "reading unloaded modules across bitness not currently supported";
|
| + return;
|
| + }
|
| + using Traits = process_types::internal::Traits64;
|
| +#elif defined(ARCH_CPU_X86)
|
| + using Traits = process_types::internal::Traits32;
|
| +#else
|
| +#error port
|
| +#endif
|
| +
|
| + RTL_UNLOAD_EVENT_TRACE<Traits>* unload_event_trace_address =
|
| + RtlGetUnloadEventTrace<Traits>();
|
| + WinVMAddress address_in_target_process =
|
| + reinterpret_cast<WinVMAddress>(unload_event_trace_address);
|
| +
|
| + std::vector<RTL_UNLOAD_EVENT_TRACE<Traits>> events(
|
| + RTL_UNLOAD_EVENT_TRACE_NUMBER);
|
| + if (!process_reader_.ReadMemory(address_in_target_process,
|
| + events.size() * sizeof(events[0]),
|
| + &events[0])) {
|
| + return;
|
| + }
|
| +
|
| + for (const RTL_UNLOAD_EVENT_TRACE<Traits>& uet : events) {
|
| + if (uet.ImageName[0]) {
|
| + unloaded_modules_.push_back(UnloadedModuleSnapshot(
|
| + uet.BaseAddress,
|
| + uet.SizeOfImage,
|
| + uet.CheckSum,
|
| + uet.TimeDateStamp,
|
| + base::UTF16ToUTF8(
|
| + base::StringPiece16(uet.ImageName, arraysize(uet.ImageName)))));
|
| + }
|
| + }
|
| +}
|
| +
|
| void ProcessSnapshotWin::GetCrashpadOptionsInternal(
|
| CrashpadInfoClientOptions* options) {
|
| CrashpadInfoClientOptions local_options;
|
|
|