diff options
author | ivan.penkov@gmail.com <ivan.penkov@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-06-27 20:34:30 +0000 |
---|---|---|
committer | ivan.penkov@gmail.com <ivan.penkov@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-06-27 20:34:30 +0000 |
commit | d394434a93a7dda8b6f1701327a2887d4892e3e6 (patch) | |
tree | 1b4e25cab21fb32087c58ffabe7b64ff399364dc /src/processor/minidump.cc | |
parent | More robust stack walks when the IP address in the context frame is invalid (... (diff) | |
download | breakpad-d394434a93a7dda8b6f1701327a2887d4892e3e6.tar.xz |
This change is addressing a particularly nasty issue where the stackwalker
doesn't see the correct thread stack memory. Instead, it loads garbage
(from offset 0 of the minidump file - well that's not garbage, but it is
not the stack memory region either) and attempts to walk it. A typical
symptom of this issue is when you get a single stack frame after
processing - the context frame - for which you don't need stack memory.
This issue is caused by an invalid RVA in the memory descriptor stored
inside the MINIDUMP_THREAD structure for the thread. Luckily, the
invalid RVA is 0, and the start_of_memory_region appears to be correct,
so this issue can be easily detected and the correct memory region can be
loaded using an RVA specified in the MinidumpMemoryList.
I couldn't find a reasonable description on MSDN regarding
MINIDUMP_MEMORY_DESCRIPTOR.MINIDUMP_LOCATION_DESCRIPTOR having RVA of 0
except maybe for full dumps where the 64-bit version of the structure
(MINIDUMP_MEMORY_DESCRIPTOR64) is used and it has no RVA at all. It has
a 64-bit DataSize which if interpreted as the 32-bit structure will very
likely result in 0 for the RVA:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680384(v=vs.85).aspx
Anyways, the dump that I looked at was not a full dump so 0 for RVA is a
bit puzzling (at least easily detectable):
...
Microsoft (R) Windows Debugger Version 6.2.9200.20512 X86
Copyright (c) Microsoft Corporation. All rights reserved.
...
User Mini Dump File: Only registers, stack and portions of memory are available
...
MINIDUMP_HEADER:
Version A793 (62F0)
NumberOfStreams 11
Flags 160
0020 MiniDumpWithUnloadedModules
0040 MiniDumpWithIndirectlyReferencedMemory
0100 MiniDumpWithProcessThreadData
Review URL: https://breakpad.appspot.com/606002
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1194 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/processor/minidump.cc')
-rwxr-xr-x | src/processor/minidump.cc | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 4ad82053..7ad736d5 100755 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -1509,13 +1509,15 @@ bool MinidumpThread::Read() { } // Check for base + size overflow or undersize. - if (thread_.stack.memory.data_size == 0 || + if (thread_.stack.memory.rva == 0 || + thread_.stack.memory.data_size == 0 || thread_.stack.memory.data_size > numeric_limits<uint64_t>::max() - thread_.stack.start_of_memory_range) { // This is ok, but log an error anyway. BPLOG(ERROR) << "MinidumpThread has a memory region problem, " << HexString(thread_.stack.start_of_memory_range) << "+" << - HexString(thread_.stack.memory.data_size); + HexString(thread_.stack.memory.data_size) << + ", RVA 0x" << HexString(thread_.stack.memory.rva); } else { memory_ = new MinidumpMemoryRegion(minidump_); memory_->SetDescriptor(&thread_.stack); @@ -1525,6 +1527,14 @@ bool MinidumpThread::Read() { return true; } +uint64_t MinidumpThread::GetStartOfStackMemoryRange() const { + if (!valid_) { + BPLOG(ERROR) << "GetStartOfStackMemoryRange: Invalid MinidumpThread"; + return 0; + } + + return thread_.stack.start_of_memory_range; +} MinidumpMemoryRegion* MinidumpThread::GetMemory() { if (!valid_) { |