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
This commit is contained in:
parent
374e8dcfa7
commit
d394434a93
4 changed files with 76 additions and 14 deletions
|
@ -122,6 +122,12 @@ ProcessResult MinidumpProcessor::Process(
|
|||
if (module_list)
|
||||
process_state->modules_ = module_list->Copy();
|
||||
|
||||
MinidumpMemoryList *memory_list = dump->GetMemoryList();
|
||||
if (memory_list) {
|
||||
BPLOG(INFO) << "Found " << memory_list->region_count()
|
||||
<< " memory regions.";
|
||||
}
|
||||
|
||||
MinidumpThreadList *threads = dump->GetThreadList();
|
||||
if (!threads) {
|
||||
BPLOG(ERROR) << "Minidump " << dump->path() << " has no thread list";
|
||||
|
@ -208,7 +214,17 @@ ProcessResult MinidumpProcessor::Process(
|
|||
}
|
||||
}
|
||||
|
||||
// If the memory region for the stack cannot be read using the RVA stored
|
||||
// in the memory descriptor inside MINIDUMP_THREAD, try to locate and use
|
||||
// a memory region (containing the stack) from the minidump memory list.
|
||||
MinidumpMemoryRegion *thread_memory = thread->GetMemory();
|
||||
if (!thread_memory && memory_list) {
|
||||
uint64_t start_stack_memory_range = thread->GetStartOfStackMemoryRange();
|
||||
if (start_stack_memory_range) {
|
||||
thread_memory = memory_list->GetMemoryRegionForAddress(
|
||||
start_stack_memory_range);
|
||||
}
|
||||
}
|
||||
if (!thread_memory) {
|
||||
BPLOG(ERROR) << "No memory region for " << thread_string;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue