| Index: snapshot/win/process_snapshot_win.cc
|
| diff --git a/snapshot/win/process_snapshot_win.cc b/snapshot/win/process_snapshot_win.cc
|
| index b8498d6c6c27fa8e081d1e58cd048f1fd5ad3532..8c184c26b9ab502b49048c32d93a21a8a4b737bc 100644
|
| --- a/snapshot/win/process_snapshot_win.cc
|
| +++ b/snapshot/win/process_snapshot_win.cc
|
| @@ -326,15 +326,16 @@ void ProcessSnapshotWin::InitializePebData(
|
| DetermineSizeOfEnvironmentBlock(process_parameters.Environment),
|
| &extra_memory_);
|
|
|
| - // Walk the loader lock which is directly referenced by the PEB. It may or may
|
| - // not have a .DebugInfo list, but doesn't on more recent OSs (it does on
|
| - // Vista). If it does, then we may walk the lock list more than once, but
|
| - // AddMemorySnapshot() will take care of deduplicating the added regions.
|
| - ReadLocks<Traits>(peb_data.LoaderLock, &extra_memory_);
|
| -
|
| - // Traverse the locks with valid .DebugInfo if a starting point was supplied.
|
| - if (debug_critical_section_address)
|
| - ReadLocks<Traits>(debug_critical_section_address, &extra_memory_);
|
| + // Walk the loader lock which is directly referenced by the PEB.
|
| + ReadLock<Traits>(peb_data.LoaderLock, &extra_memory_);
|
| +
|
| + // TODO(scottmg): Use debug_critical_section_address to walk the list of
|
| + // locks (see history of this file for walking code). In some configurations
|
| + // this can walk many thousands of locks, so we may want to get some
|
| + // annotation from the client for which locks to grab. Unfortunately, without
|
| + // walking the list, the !locks command in windbg won't work because it
|
| + // requires the lock pointed to by ntdll!RtlCriticalSectionList, which we
|
| + // won't have captured.
|
| }
|
|
|
| void ProcessSnapshotWin::AddMemorySnapshot(
|
| @@ -425,7 +426,7 @@ WinVMSize ProcessSnapshotWin::DetermineSizeOfEnvironmentBlock(
|
| }
|
|
|
| template <class Traits>
|
| -void ProcessSnapshotWin::ReadLocks(
|
| +void ProcessSnapshotWin::ReadLock(
|
| WinVMAddress start,
|
| PointerVector<internal::MemorySnapshotWin>* into) {
|
| // We're walking the RTL_CRITICAL_SECTION_DEBUG ProcessLocksList, but starting
|
| @@ -439,82 +440,17 @@ void ProcessSnapshotWin::ReadLocks(
|
| return;
|
| }
|
|
|
| + AddMemorySnapshot(
|
| + start, sizeof(process_types::RTL_CRITICAL_SECTION<Traits>), into);
|
| +
|
| const decltype(critical_section.DebugInfo) kInvalid =
|
| static_cast<decltype(critical_section.DebugInfo)>(-1);
|
| if (critical_section.DebugInfo == kInvalid)
|
| return;
|
|
|
| - const WinVMAddress start_address_backward = critical_section.DebugInfo;
|
| - WinVMAddress current_address = start_address_backward;
|
| - WinVMAddress last_good_address;
|
| -
|
| - // Typically, this seems to be a circular list, but it's not clear that it
|
| - // always is, so follow Blink fields back to the head (or where we started)
|
| - // before following Flink to capture memory.
|
| - do {
|
| - last_good_address = current_address;
|
| - // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList.
|
| - process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug;
|
| - if (!process_reader_.ReadMemory(current_address,
|
| - sizeof(critical_section_debug),
|
| - &critical_section_debug)) {
|
| - LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG";
|
| - return;
|
| - }
|
| -
|
| - if (critical_section_debug.ProcessLocksList.Blink == 0) {
|
| - // At the head of the list.
|
| - break;
|
| - }
|
| -
|
| - // Move to the previous RTL_CRITICAL_SECTION_DEBUG by walking
|
| - // ProcessLocksList.Blink.
|
| - current_address =
|
| - critical_section_debug.ProcessLocksList.Blink -
|
| - offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>,
|
| - ProcessLocksList);
|
| - } while (current_address != start_address_backward &&
|
| - current_address != kInvalid);
|
| -
|
| - if (current_address == kInvalid) {
|
| - // Unexpectedly encountered a bad record, so step back one.
|
| - current_address = last_good_address;
|
| - }
|
| -
|
| - const WinVMAddress start_address_forward = current_address;
|
| -
|
| - // current_address is now the head of the list, walk Flink to add the whole
|
| - // list.
|
| - do {
|
| - // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList.
|
| - process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug;
|
| - if (!process_reader_.ReadMemory(current_address,
|
| - sizeof(critical_section_debug),
|
| - &critical_section_debug)) {
|
| - LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG";
|
| - return;
|
| - }
|
| -
|
| - // Add both RTL_CRITICAL_SECTION_DEBUG and RTL_CRITICAL_SECTION to the extra
|
| - // memory to be saved.
|
| - AddMemorySnapshot(current_address,
|
| - sizeof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>),
|
| - into);
|
| - AddMemorySnapshot(critical_section_debug.CriticalSection,
|
| - sizeof(process_types::RTL_CRITICAL_SECTION<Traits>),
|
| - into);
|
| -
|
| - if (critical_section_debug.ProcessLocksList.Flink == 0)
|
| - break;
|
| -
|
| - // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking
|
| - // ProcessLocksList.Flink.
|
| - current_address =
|
| - critical_section_debug.ProcessLocksList.Flink -
|
| - offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>,
|
| - ProcessLocksList);
|
| - } while (current_address != start_address_forward &&
|
| - current_address != kInvalid);
|
| + AddMemorySnapshot(critical_section.DebugInfo,
|
| + sizeof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>),
|
| + into);
|
| }
|
|
|
| } // namespace crashpad
|
|
|