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:
ivan.penkov@gmail.com
2013-06-27 20:34:30 +00:00
parent 374e8dcfa7
commit d394434a93
4 changed files with 76 additions and 14 deletions

View File

@@ -326,6 +326,11 @@ class MinidumpThread : public MinidumpObject {
// Print a human-readable representation of the object to stdout.
void Print();
// Returns the start address of the thread stack memory region. Returns 0 if
// MinidumpThread is invalid. Note that this method can be called even when
// the thread memory cannot be read and GetMemory returns NULL.
virtual uint64_t GetStartOfStackMemoryRange() const;
protected:
explicit MinidumpThread(Minidump* minidump);
@@ -586,13 +591,14 @@ class MinidumpMemoryList : public MinidumpStream {
// Random access to memory regions. Returns the region encompassing
// the address identified by address.
MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);
virtual MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);
// Print a human-readable representation of the object to stdout.
void Print();
private:
friend class Minidump;
friend class MockMinidumpMemoryList;
typedef vector<MDMemoryDescriptor> MemoryDescriptors;
typedef vector<MinidumpMemoryRegion> MemoryRegions;
@@ -932,7 +938,7 @@ class Minidump {
// parameter).
virtual MinidumpThreadList* GetThreadList();
MinidumpModuleList* GetModuleList();
MinidumpMemoryList* GetMemoryList();
virtual MinidumpMemoryList* GetMemoryList();
MinidumpException* GetException();
MinidumpAssertion* GetAssertion();
virtual MinidumpSystemInfo* GetSystemInfo();