Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Unified Diff: snapshot/win/process_snapshot_win.cc

Issue 1360863006: win: Add more memory regions to gathering of PEB (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@save-peb
Patch Set: . Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « snapshot/win/process_snapshot_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: snapshot/win/process_snapshot_win.cc
diff --git a/snapshot/win/process_snapshot_win.cc b/snapshot/win/process_snapshot_win.cc
index b9df62c0ab4c011109ab9054f5b556141958d658..29c9db58ffe44d19fa8475f12ed2210b7ac6f793 100644
--- a/snapshot/win/process_snapshot_win.cc
+++ b/snapshot/win/process_snapshot_win.cc
@@ -14,6 +14,8 @@
#include "snapshot/win/process_snapshot_win.h"
+#include <algorithm>
+
#include "base/logging.h"
#include "snapshot/win/module_snapshot_win.h"
#include "util/win/registration_protocol_win.h"
@@ -48,10 +50,11 @@ bool ProcessSnapshotWin::Initialize(HANDLE process,
return false;
system_.Initialize(&process_reader_);
- WinVMAddress peb_address;
- WinVMSize peb_size;
- process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size);
- peb_.Initialize(&process_reader_, peb_address, peb_size);
+
+ if (process_reader_.Is64Bit())
+ InitializePebData<process_types::internal::Traits64>();
+ else
+ InitializePebData<process_types::internal::Traits32>();
InitializeThreads();
InitializeModules();
@@ -186,7 +189,8 @@ const ExceptionSnapshot* ProcessSnapshotWin::Exception() const {
std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
std::vector<const MemorySnapshot*> extra_memory;
- extra_memory.push_back(&peb_);
+ for (const auto& peb_memory : peb_memory_)
+ extra_memory.push_back(peb_memory);
return extra_memory;
}
@@ -214,4 +218,144 @@ void ProcessSnapshotWin::InitializeModules() {
}
}
+template <class Traits>
+void ProcessSnapshotWin::InitializePebData() {
+ WinVMAddress peb_address;
+ WinVMSize peb_size;
+ process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size);
+ AddMemorySnapshot(peb_address, peb_size, &peb_memory_);
+
+ process_types::PEB<Traits> peb_data;
+ if (!process_reader_.ReadMemory(peb_address, peb_size, &peb_data)) {
+ LOG(ERROR) << "ReadMemory PEB";
+ return;
+ }
+
+ process_types::PEB_LDR_DATA<Traits> peb_ldr_data;
+ AddMemorySnapshot(
+ peb_data.Ldr, sizeof(peb_ldr_data), &peb_memory_);
+ if (!process_reader_.ReadMemory(
+ peb_data.Ldr, sizeof(peb_ldr_data), &peb_ldr_data)) {
+ LOG(ERROR) << "ReadMemory PEB_LDR_DATA";
+ return;
Mark Mentovai 2015/09/29 21:57:11 Don’t bail out here. You still might be able to sa
scottmg 2015/09/30 18:19:40 Done.
+ }
+
+ // Walk the LDR structure to retrieve its pointed-to data. We don't care too
Mark Mentovai 2015/09/29 21:57:10 Question: does MiniDumpWriteDump() collect these r
scottmg 2015/09/30 18:19:40 Doesn't look like MiniDumpWriteDump() grabs the LD
Mark Mentovai 2015/10/01 19:05:47 No real objection to including this, I’m just tryi
scottmg 2015/10/01 20:17:00 I'll include it for now then as it's nice to have
+ // much about this here as we have the data in other places already, but
+ // without it Windbg's `!peb` gets confused and won't dump other useful data
+ // in the PEB.
+ AddMemorySnapshotForLdrLIST_ENTRY(
Mark Mentovai 2015/09/29 21:57:11 I’ve got a new concern. A lot of the extra memory
scottmg 2015/09/30 18:19:40 Yeah, all good points. In general, I don't like h
Mark Mentovai 2015/10/01 19:05:47 scottmg wrote:
scottmg 2015/10/01 20:17:00 Good point. It's pretty localized at the moment, s
+ peb_ldr_data.InLoadOrderModuleList,
+ offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, InLoadOrderLinks),
+ &peb_memory_);
+ AddMemorySnapshotForLdrLIST_ENTRY(
+ peb_ldr_data.InMemoryOrderModuleList,
+ offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, InMemoryOrderLinks),
+ &peb_memory_);
+ AddMemorySnapshotForLdrLIST_ENTRY(
+ peb_ldr_data.InInitializationOrderModuleList,
+ offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>,
+ InInitializationOrderLinks),
+ &peb_memory_);
+
+ process_types::RTL_USER_PROCESS_PARAMETERS<Traits> process_parameters;
+ if (!process_reader_.ReadMemory(peb_data.ProcessParameters,
+ sizeof(process_parameters),
+ &process_parameters)) {
+ LOG(ERROR) << "ReadMemory RTL_USER_PROCESS_PARAMETERS";
+ return;
+ }
+ AddMemorySnapshot(
+ peb_data.ProcessParameters, sizeof(process_parameters), &peb_memory_);
+
+ AddMemorySnapshotForUNICODE_STRING(
+ process_parameters.CurrentDirectory.DosPath, &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.DllPath, &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.ImagePathName,
+ &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.CommandLine,
+ &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.WindowTitle,
+ &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.DesktopInfo,
+ &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.ShellInfo,
+ &peb_memory_);
+ AddMemorySnapshotForUNICODE_STRING(process_parameters.RuntimeData,
+ &peb_memory_);
+ AddMemorySnapshot(
+ process_parameters.Environment,
+ DetermineSizeOfEnvironmentBlock(process_parameters.Environment),
+ &peb_memory_);
+}
+
+void ProcessSnapshotWin::AddMemorySnapshot(
+ WinVMAddress address,
+ WinVMSize size,
+ PointerVector<internal::MemorySnapshotWin>* into) {
+ if (size == 0)
+ return;
+ internal::MemorySnapshotWin* memory_snapshot =
+ new internal::MemorySnapshotWin();
+ memory_snapshot->Initialize(&process_reader_, address, size);
+ into->push_back(memory_snapshot);
+}
+
+template <class Traits>
+void ProcessSnapshotWin::AddMemorySnapshotForUNICODE_STRING(
+ const process_types::UNICODE_STRING<Traits>& us,
+ PointerVector<internal::MemorySnapshotWin>* into) {
+ AddMemorySnapshot(us.Buffer, us.Length, into);
+}
+
+template <class Traits>
+void ProcessSnapshotWin::AddMemorySnapshotForLdrLIST_ENTRY(
+ const process_types::LIST_ENTRY<Traits>& le, size_t offset_of_member,
+ PointerVector<internal::MemorySnapshotWin>* into) {
+ // Walk the doubly-linked list of entries, adding the list memory itself, as
+ // well as pointed-to strings.
+ Traits::Pointer last = le.Blink;
+ process_types::LDR_DATA_TABLE_ENTRY<Traits> entry;
+ Traits::Pointer cur = le.Flink;
+ for (;;) {
+ // |cur| is the pointer to LIST_ENTRY embedded in the LDR_DATA_TABLE_ENTRY.
+ // So we need to offset back to the beginning of the structure.
+ if (!process_reader_.ReadMemory(
+ cur - offset_of_member, sizeof(entry), &entry)) {
+ return;
+ }
+ AddMemorySnapshot(cur - offset_of_member, sizeof(entry), into);
+ AddMemorySnapshotForUNICODE_STRING(entry.FullDllName, into);
+ AddMemorySnapshotForUNICODE_STRING(entry.BaseDllName, into);
+
+ process_types::LIST_ENTRY<Traits>* links =
+ reinterpret_cast<process_types::LIST_ENTRY<Traits>*>(
+ reinterpret_cast<unsigned char*>(&entry) + offset_of_member);
+ cur = links->Flink;
+ if (cur == last)
+ break;
+ }
+}
+
+WinVMSize ProcessSnapshotWin::DetermineSizeOfEnvironmentBlock(
+ WinVMAddress start_of_environment_block) {
+ // http://blogs.msdn.com/b/oldnewthing/archive/2010/02/03/9957320.aspx On
+ // newer OSs there's no stated limit, but in practice grabbing 32k characters
+ // should be more than enough.
+ std::wstring env_block;
+ env_block.resize(32768);
+ WinVMSize bytes_read = process_reader_.ReadAvailableMemory(
+ start_of_environment_block,
+ env_block.size() * sizeof(env_block[0]),
+ &env_block[0]);
+ env_block.resize(
+ static_cast<unsigned int>(bytes_read / sizeof(env_block[0])));
+ const wchar_t terminator[] = { 0, 0 };
+ size_t at = env_block.find(std::wstring(terminator, arraysize(terminator)));
+ if (at != std::wstring::npos)
+ env_block.resize(at + arraysize(terminator));
+
+ return env_block.size() * sizeof(env_block[0]);
+}
+
} // namespace crashpad
« no previous file with comments | « snapshot/win/process_snapshot_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698