Allow processing dumps with missing stack memory for some threads

r=mkrebs at https://breakpad.appspot.com/413002/

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1077 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek@gmail.com 2012-11-06 16:50:01 +00:00
parent 66a21aad61
commit fc6f700bb5
16 changed files with 412 additions and 92 deletions

View file

@ -190,31 +190,13 @@ class MinidumpContext : public MinidumpStream {
const MDRawContextPPC* GetContextPPC() const;
const MDRawContextSPARC* GetContextSPARC() const;
const MDRawContextX86* GetContextX86() const;
// Print a human-readable representation of the object to stdout.
void Print();
private:
friend class MinidumpThread;
friend class MinidumpException;
protected:
explicit MinidumpContext(Minidump* minidump);
bool Read(u_int32_t expected_size);
// Free the CPU-specific context structure.
void FreeContext();
// If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
// system info stream gives an appropriate CPU type matching the context
// CPU type in context_cpu_type. Returns false if the CPU type does not
// match. Returns true if the CPU type matches or if the minidump does
// not contain a system info stream.
bool CheckAgainstSystemInfo(u_int32_t context_cpu_type);
// Store this separately because of the weirdo AMD64 context
u_int32_t context_flags_;
// The CPU-specific context structure.
union {
MDRawContextBase* base;
@ -226,6 +208,25 @@ class MinidumpContext : public MinidumpStream {
MDRawContextSPARC* ctx_sparc;
MDRawContextARM* arm;
} context_;
// Store this separately because of the weirdo AMD64 context
u_int32_t context_flags_;
private:
friend class MinidumpThread;
friend class MinidumpException;
bool Read(u_int32_t expected_size);
// Free the CPU-specific context structure.
void FreeContext();
// If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
// system info stream gives an appropriate CPU type matching the context
// CPU type in context_cpu_type. Returns false if the CPU type does not
// match. Returns true if the CPU type matches or if the minidump does
// not contain a system info stream.
bool CheckAgainstSystemInfo(u_int32_t context_cpu_type);
};
@ -268,12 +269,13 @@ class MinidumpMemoryRegion : public MinidumpObject,
// Print a human-readable representation of the object to stdout.
void Print();
protected:
explicit MinidumpMemoryRegion(Minidump* minidump);
private:
friend class MinidumpThread;
friend class MinidumpMemoryList;
explicit MinidumpMemoryRegion(Minidump* minidump);
// Identify the base address and size of the memory region, and the
// location it may be found in the minidump file.
void SetDescriptor(MDMemoryDescriptor* descriptor);
@ -300,29 +302,35 @@ class MinidumpMemoryRegion : public MinidumpObject,
// the thread that caused an exception, the context carried by
// MinidumpException is probably desired instead of the CPU context
// provided here.
// Note that a MinidumpThread may be valid() even if it does not
// contain a memory region or context.
class MinidumpThread : public MinidumpObject {
public:
virtual ~MinidumpThread();
const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
MinidumpMemoryRegion* GetMemory();
MinidumpContext* GetContext();
// GetMemory may return NULL even if the MinidumpThread is valid,
// if the thread memory cannot be read.
virtual MinidumpMemoryRegion* GetMemory();
// GetContext may return NULL even if the MinidumpThread is valid.
virtual MinidumpContext* GetContext();
// The thread ID is used to determine if a thread is the exception thread,
// so a special getter is provided to retrieve this data from the
// MDRawThread structure. Returns false if the thread ID cannot be
// determined.
bool GetThreadID(u_int32_t *thread_id) const;
virtual bool GetThreadID(u_int32_t *thread_id) const;
// Print a human-readable representation of the object to stdout.
void Print();
protected:
explicit MinidumpThread(Minidump* minidump);
private:
// These objects are managed by MinidumpThreadList.
friend class MinidumpThreadList;
explicit MinidumpThread(Minidump* minidump);
// This works like MinidumpStream::Read, but is driven by
// MinidumpThreadList. No size checking is done, because
// MinidumpThreadList handles that directly.
@ -345,12 +353,12 @@ class MinidumpThreadList : public MinidumpStream {
}
static u_int32_t max_threads() { return max_threads_; }
unsigned int thread_count() const {
virtual unsigned int thread_count() const {
return valid_ ? thread_count_ : 0;
}
// Sequential access to threads.
MinidumpThread* GetThreadAtIndex(unsigned int index) const;
virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const;
// Random access to threads.
MinidumpThread* GetThreadByID(u_int32_t thread_id);
@ -358,6 +366,9 @@ class MinidumpThreadList : public MinidumpStream {
// Print a human-readable representation of the object to stdout.
void Print();
protected:
explicit MinidumpThreadList(Minidump* aMinidump);
private:
friend class Minidump;
@ -366,8 +377,6 @@ class MinidumpThreadList : public MinidumpStream {
static const u_int32_t kStreamType = MD_THREAD_LIST_STREAM;
explicit MinidumpThreadList(Minidump* aMinidump);
bool Read(u_int32_t aExpectedSize);
// The largest number of threads that will be read from a minidump. The
@ -526,6 +535,9 @@ class MinidumpModuleList : public MinidumpStream,
// Print a human-readable representation of the object to stdout.
void Print();
protected:
explicit MinidumpModuleList(Minidump* minidump);
private:
friend class Minidump;
@ -533,8 +545,6 @@ class MinidumpModuleList : public MinidumpStream,
static const u_int32_t kStreamType = MD_MODULE_LIST_STREAM;
explicit MinidumpModuleList(Minidump* minidump);
bool Read(u_int32_t expected_size);
// The largest number of modules that will be read from a minidump. The
@ -722,21 +732,21 @@ class MinidumpSystemInfo : public MinidumpStream {
// Print a human-readable representation of the object to stdout.
void Print();
private:
friend class Minidump;
static const u_int32_t kStreamType = MD_SYSTEM_INFO_STREAM;
protected:
explicit MinidumpSystemInfo(Minidump* minidump);
bool Read(u_int32_t expected_size);
MDRawSystemInfo system_info_;
// Textual representation of the OS service pack, for minidumps produced
// by MiniDumpWriteDump on Windows.
const string* csd_version_;
private:
friend class Minidump;
static const u_int32_t kStreamType = MD_SYSTEM_INFO_STREAM;
bool Read(u_int32_t expected_size);
// A string identifying the CPU vendor, if known.
const string* cpu_vendor_;
};
@ -913,7 +923,7 @@ class Minidump {
MinidumpMemoryList* GetMemoryList();
MinidumpException* GetException();
MinidumpAssertion* GetAssertion();
MinidumpSystemInfo* GetSystemInfo();
virtual MinidumpSystemInfo* GetSystemInfo();
MinidumpMiscInfo* GetMiscInfo();
MinidumpBreakpadInfo* GetBreakpadInfo();
MinidumpMemoryInfoList* GetMemoryInfoList();

View file

@ -73,15 +73,6 @@ enum ProcessResult {
// one requesting
// thread.
PROCESS_ERROR_NO_MEMORY_FOR_THREAD, // A thread had no
// memory region.
PROCESS_ERROR_NO_STACKWALKER_FOR_THREAD, // We couldn't
// determine the
// StackWalker to walk
// the minidump's
// threads.
PROCESS_SYMBOL_SUPPLIER_INTERRUPTED // The minidump
// processing was
// interrupted by the