Refactoring in preparation for microdump processing

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1370 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
mmandlis@chromium.org
2014-09-08 19:10:42 +00:00
parent a58de86bcd
commit 54c2560a82
22 changed files with 1058 additions and 666 deletions

View File

@@ -0,0 +1,112 @@
// Copyright (c) 2014 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// dump_context.h: A (mini/micro) dump CPU-specific context.
#ifndef GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__
#define GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__
#include "google_breakpad/common/minidump_format.h"
#include "google_breakpad/processor/dump_object.h"
namespace google_breakpad {
// DumpContext carries a CPU-specific MDRawContext structure, which contains CPU
// context such as register states.
class DumpContext : public DumpObject {
public:
virtual ~DumpContext();
// Returns an MD_CONTEXT_* value such as MD_CONTEXT_X86 or MD_CONTEXT_PPC
// identifying the CPU type that the context was collected from. The
// returned value will identify the CPU only, and will have any other
// MD_CONTEXT_* bits masked out. Returns 0 on failure.
uint32_t GetContextCPU() const;
// Return the raw value of |context_flags_|
uint32_t GetContextFlags() const;
// Returns raw CPU-specific context data for the named CPU type. If the
// context data does not match the CPU type or does not exist, returns NULL.
const MDRawContextAMD64* GetContextAMD64() const;
const MDRawContextARM* GetContextARM() const;
const MDRawContextARM64* GetContextARM64() const;
const MDRawContextMIPS* GetContextMIPS() const;
const MDRawContextPPC* GetContextPPC() const;
const MDRawContextPPC64* GetContextPPC64() const;
const MDRawContextSPARC* GetContextSPARC() const;
const MDRawContextX86* GetContextX86() const;
// A convenience method to get the instruction pointer out of the
// MDRawContext, since it varies per-CPU architecture.
bool GetInstructionPointer(uint64_t* ip) const;
// Print a human-readable representation of the object to stdout.
void Print();
protected:
DumpContext();
// Sets row CPU-specific context data for the names CPU type.
void SetContextFlags(uint32_t context_flags);
void SetContextX86(MDRawContextX86* x86);
void SetContextPPC(MDRawContextPPC* ppc);
void SetContextPPC64(MDRawContextPPC64* ppc64);
void SetContextAMD64(MDRawContextAMD64* amd64);
void SetContextSPARC(MDRawContextSPARC* ctx_sparc);
void SetContextARM(MDRawContextARM* arm);
void SetContextARM64(MDRawContextARM64* arm64);
void SetContextMIPS(MDRawContextMIPS* ctx_mips);
// Free the CPU-specific context structure.
void FreeContext();
private:
// The CPU-specific context structure.
union {
MDRawContextBase* base;
MDRawContextX86* x86;
MDRawContextPPC* ppc;
MDRawContextPPC64* ppc64;
MDRawContextAMD64* amd64;
// on Solaris SPARC, sparc is defined as a numeric constant,
// so variables can NOT be named as sparc
MDRawContextSPARC* ctx_sparc;
MDRawContextARM* arm;
MDRawContextARM64* arm64;
MDRawContextMIPS* ctx_mips;
} context_;
// Store this separately because of the weirdo AMD64 context
uint32_t context_flags_;
};
} // namespace google_breakpad
#endif // GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2014 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// dump_object.h: A base class for all mini/micro dump object.
#ifndef GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__
#define GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__
namespace google_breakpad {
// DumpObject is the base of various mini/micro dump's objects.
class DumpObject {
public:
DumpObject();
bool valid() const { return valid_; }
protected:
// DumpObjects are not valid when created. When a subclass populates its own
// fields, it can set valid_ to true. Accessors and mutators may wish to
// consider or alter the valid_ state as they interact with objects.
bool valid_;
};
} // namespace google_breakpad
#endif // GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__

View File

@@ -67,6 +67,9 @@ class MemoryRegion {
virtual bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const = 0;
virtual bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const = 0;
virtual bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const = 0;
// Print a human-readable representation of the object to stdout.
virtual void Print() const = 0;
};

View File

@@ -89,9 +89,10 @@
#include <vector>
#include "common/using_std_string.h"
#include "google_breakpad/common/minidump_format.h"
#include "google_breakpad/processor/code_module.h"
#include "google_breakpad/processor/code_modules.h"
#include "google_breakpad/processor/dump_context.h"
#include "google_breakpad/processor/dump_object.h"
#include "google_breakpad/processor/memory_region.h"
@@ -108,12 +109,10 @@ template<typename AddressType, typename EntryType> class RangeMap;
// MinidumpObject is the base of all Minidump* objects except for Minidump
// itself.
class MinidumpObject {
class MinidumpObject : public DumpObject {
public:
virtual ~MinidumpObject() {}
bool valid() const { return valid_; }
protected:
explicit MinidumpObject(Minidump* minidump);
@@ -124,21 +123,14 @@ class MinidumpObject {
// for access to data about the minidump file itself, such as whether
// it should be byte-swapped.
Minidump* minidump_;
// MinidumpObjects are not valid when created. When a subclass populates
// its own fields, it can set valid_ to true. Accessors and mutators may
// wish to consider or alter the valid_ state as they interact with
// objects.
bool valid_;
};
// This class exists primarily to provide a virtual destructor in a base
// class common to all objects that might be stored in
// Minidump::mStreamObjects. Some object types (MinidumpContext) will
// never be stored in Minidump::mStreamObjects, but are represented as
// streams and adhere to the same interface, and may be derived from
// this class.
// Minidump::mStreamObjects. Some object types will never be stored in
// Minidump::mStreamObjects, but are represented as streams and adhere to the
// same interface, and may be derived from this class.
class MinidumpStream : public MinidumpObject {
public:
virtual ~MinidumpStream() {}
@@ -168,71 +160,33 @@ class MinidumpStream : public MinidumpObject {
// context for the exception handler (which performs minidump generation),
// and not the context that caused the exception (which is probably what the
// user wants).
class MinidumpContext : public MinidumpStream {
class MinidumpContext : public DumpContext {
public:
virtual ~MinidumpContext();
// Returns an MD_CONTEXT_* value such as MD_CONTEXT_X86 or MD_CONTEXT_PPC
// identifying the CPU type that the context was collected from. The
// returned value will identify the CPU only, and will have any other
// MD_CONTEXT_* bits masked out. Returns 0 on failure.
uint32_t GetContextCPU() const;
// A convenience method to get the instruction pointer out of the
// MDRawContext, since it varies per-CPU architecture.
bool GetInstructionPointer(uint64_t* ip) const;
// Returns raw CPU-specific context data for the named CPU type. If the
// context data does not match the CPU type or does not exist, returns
// NULL.
const MDRawContextAMD64* GetContextAMD64() const;
const MDRawContextARM* GetContextARM() const;
const MDRawContextARM64* GetContextARM64() const;
const MDRawContextMIPS* GetContextMIPS() const;
const MDRawContextPPC* GetContextPPC() const;
const MDRawContextPPC64* GetContextPPC64() const;
const MDRawContextSPARC* GetContextSPARC() const;
const MDRawContextX86* GetContextX86() const;
// Print a human-readable representation of the object to stdout.
void Print();
protected:
explicit MinidumpContext(Minidump* minidump);
// The CPU-specific context structure.
union {
MDRawContextBase* base;
MDRawContextX86* x86;
MDRawContextPPC* ppc;
MDRawContextPPC64* ppc64;
MDRawContextAMD64* amd64;
// on Solaris SPARC, sparc is defined as a numeric constant,
// so variables can NOT be named as sparc
MDRawContextSPARC* ctx_sparc;
MDRawContextARM* arm;
MDRawContextARM64* arm64;
MDRawContextMIPS* ctx_mips;
} context_;
// Store this separately because of the weirdo AMD64 context
uint32_t context_flags_;
private:
friend class MinidumpThread;
friend class MinidumpException;
bool Read(uint32_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(uint32_t context_cpu_type);
// Refers to the Minidump object that is the ultimate parent of this
// Some MinidumpObjects are owned by other MinidumpObjects, but at the
// root of the ownership tree is always a Minidump. The Minidump object
// is kept here for access to its seeking and reading facilities, and
// for access to data about the minidump file itself, such as whether
// it should be byte-swapped.
Minidump* minidump_;
};
@@ -273,7 +227,7 @@ class MinidumpMemoryRegion : public MinidumpObject,
bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const;
// Print a human-readable representation of the object to stdout.
void Print();
void Print() const;
protected:
explicit MinidumpMemoryRegion(Minidump* minidump);
@@ -634,10 +588,10 @@ class MinidumpMemoryList : public MinidumpStream {
// MinidumpException wraps MDRawExceptionStream, which contains information
// about the exception that caused the minidump to be generated, if the
// minidump was generated in an exception handler called as a result of
// an exception. It also provides access to a MinidumpContext object,
// which contains the CPU context for the exception thread at the time
// the exception occurred.
// minidump was generated in an exception handler called as a result of an
// exception. It also provides access to a MinidumpContext object, which
// contains the CPU context for the exception thread at the time the exception
// occurred.
class MinidumpException : public MinidumpStream {
public:
virtual ~MinidumpException();

View File

@@ -35,6 +35,7 @@
#include "common/using_std_string.h"
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/processor/process_result.h"
namespace google_breakpad {
@@ -44,41 +45,6 @@ class StackFrameSymbolizer;
class SourceLineResolverInterface;
class SymbolSupplier;
struct SystemInfo;
// Return type for Process()
enum ProcessResult {
PROCESS_OK, // The minidump was
// processed
// successfully.
PROCESS_ERROR_MINIDUMP_NOT_FOUND, // The minidump file
// was not found.
PROCESS_ERROR_NO_MINIDUMP_HEADER, // The minidump file
// had no header
PROCESS_ERROR_NO_THREAD_LIST, // The minidump file
// had no thread list.
PROCESS_ERROR_GETTING_THREAD, // There was an error
// getting one
// thread's data from
// the minidump.
PROCESS_ERROR_GETTING_THREAD_ID, // There was an error
// getting a thread id
// from the thread's
// data.
PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS, // There was more than
// one requesting
// thread.
PROCESS_SYMBOL_SUPPLIER_INTERRUPTED // The minidump
// processing was
// interrupted by the
// SymbolSupplier(not
// fatal)
};
class MinidumpProcessor {
public:

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__
#define GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__
namespace google_breakpad {
// Return type for MinidumpProcessor or MicrodumpProcessor's Process()
enum ProcessResult {
PROCESS_OK, // The dump was processed
// successfully.
PROCESS_ERROR_MINIDUMP_NOT_FOUND, // The minidump file was not
// found.
PROCESS_ERROR_NO_MINIDUMP_HEADER, // The minidump file had no
// header.
PROCESS_ERROR_NO_THREAD_LIST, // The minidump file has no
// thread list.
PROCESS_ERROR_GETTING_THREAD, // There was an error getting one
// thread's data from th dump.
PROCESS_ERROR_GETTING_THREAD_ID, // There was an error getting a
// thread id from the thread's
// data.
PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS, // There was more than one
// requesting thread.
PROCESS_SYMBOL_SUPPLIER_INTERRUPTED // The dump processing was
// interrupted by the
// SymbolSupplier(not fatal).
};
} // namespace google_breakpad
#endif // GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__

View File

@@ -103,7 +103,7 @@ class ProcessState {
string assertion() const { return assertion_; }
int requesting_thread() const { return requesting_thread_; }
const vector<CallStack*>* threads() const { return &threads_; }
const vector<MinidumpMemoryRegion*>* thread_memory_regions() const {
const vector<MemoryRegion*>* thread_memory_regions() const {
return &thread_memory_regions_;
}
const SystemInfo* system_info() const { return &system_info_; }
@@ -157,7 +157,7 @@ class ProcessState {
// Stacks for each thread (except possibly the exception handler
// thread) at the time of the crash.
vector<CallStack*> threads_;
vector<MinidumpMemoryRegion*> thread_memory_regions_;
vector<MemoryRegion*> thread_memory_regions_;
// OS and CPU information.
SystemInfo system_info_;

View File

@@ -54,7 +54,7 @@
namespace google_breakpad {
class CallStack;
class MinidumpContext;
class DumpContext;
class StackFrameSymbolizer;
using std::set;
@@ -86,7 +86,7 @@ class Stackwalker {
// argument. If no suitable concrete subclass exists, returns NULL.
static Stackwalker* StackwalkerForCPU(
const SystemInfo* system_info,
MinidumpContext* context,
DumpContext* context,
MemoryRegion* memory,
const CodeModules* modules,
StackFrameSymbolizer* resolver_helper);