aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/processor/memory_region.h46
-rw-r--r--src/processor/minidump.cc88
-rw-r--r--src/processor/minidump.h801
-rw-r--r--src/processor/range_map.h88
-rw-r--r--src/processor/range_map_unittest.cc22
-rw-r--r--src/processor/stackwalker.h72
-rw-r--r--src/processor/stackwalker_x86.cc4
-rw-r--r--src/processor/stackwalker_x86.h44
8 files changed, 572 insertions, 593 deletions
diff --git a/src/processor/memory_region.h b/src/processor/memory_region.h
index 83d6dbf4..c1d9f408 100644
--- a/src/processor/memory_region.h
+++ b/src/processor/memory_region.h
@@ -31,31 +31,27 @@ namespace google_airbag {
class MemoryRegion {
- public:
- virtual ~MemoryRegion() {}
-
- // The base address of this memory region.
- virtual u_int64_t GetBase() = 0;
-
- // The size of this memory region.
- virtual u_int32_t GetSize() = 0;
-
- // Access to data of various sizes within the memory region. address
- // is a pointer to read, and it must lie within the memory region as
- // defined by its base address and size. The location pointed to by
- // value is set to the value at address. Byte-swapping is performed
- // if necessary so that the value is appropriate for the running
- // program. Returns true on success. Fails and returns false if address
- // is out of the region's bounds (after considering the width of value),
- // or for other types of errors.
- virtual bool GetMemoryAtAddress(u_int64_t address,
- u_int8_t* value) = 0;
- virtual bool GetMemoryAtAddress(u_int64_t address,
- u_int16_t* value) = 0;
- virtual bool GetMemoryAtAddress(u_int64_t address,
- u_int32_t* value) = 0;
- virtual bool GetMemoryAtAddress(u_int64_t address,
- u_int64_t* value) = 0;
+ public:
+ virtual ~MemoryRegion() {}
+
+ // The base address of this memory region.
+ virtual u_int64_t GetBase() = 0;
+
+ // The size of this memory region.
+ virtual u_int32_t GetSize() = 0;
+
+ // Access to data of various sizes within the memory region. address
+ // is a pointer to read, and it must lie within the memory region as
+ // defined by its base address and size. The location pointed to by
+ // value is set to the value at address. Byte-swapping is performed
+ // if necessary so that the value is appropriate for the running
+ // program. Returns true on success. Fails and returns false if address
+ // is out of the region's bounds (after considering the width of value),
+ // or for other types of errors.
+ virtual bool GetMemoryAtAddress(u_int64_t address, u_int8_t* value) = 0;
+ virtual bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value) = 0;
+ virtual bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value) = 0;
+ virtual bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value) = 0;
};
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 2dc9dda0..6c4226b3 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -199,8 +199,8 @@ static string* UTF16ToUTF8(const vector<u_int16_t>& in,
MinidumpObject::MinidumpObject(Minidump* minidump)
- : minidump_(minidump)
- , valid_(false) {
+ : minidump_(minidump),
+ valid_(false) {
}
@@ -220,8 +220,8 @@ MinidumpStream::MinidumpStream(Minidump* minidump)
MinidumpContext::MinidumpContext(Minidump* minidump)
- : MinidumpStream(minidump)
- , context_() {
+ : MinidumpStream(minidump),
+ context_() {
}
@@ -346,9 +346,9 @@ void MinidumpContext::Print() {
MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump)
- : MinidumpObject(minidump)
- , descriptor_(NULL)
- , memory_(NULL) {
+ : MinidumpObject(minidump),
+ descriptor_(NULL),
+ memory_(NULL) {
}
@@ -481,10 +481,10 @@ void MinidumpMemoryRegion::Print() {
MinidumpThread::MinidumpThread(Minidump* minidump)
- : MinidumpObject(minidump)
- , thread_()
- , memory_(NULL)
- , context_(NULL) {
+ : MinidumpObject(minidump),
+ thread_(),
+ memory_(NULL),
+ context_(NULL) {
}
@@ -608,10 +608,10 @@ void MinidumpThread::Print() {
MinidumpThreadList::MinidumpThreadList(Minidump* minidump)
- : MinidumpStream(minidump)
- , id_to_thread_map_()
- , threads_(NULL)
- , thread_count_(0) {
+ : MinidumpStream(minidump),
+ id_to_thread_map_(),
+ threads_(NULL),
+ thread_count_(0) {
}
@@ -712,12 +712,12 @@ void MinidumpThreadList::Print() {
MinidumpModule::MinidumpModule(Minidump* minidump)
- : MinidumpObject(minidump)
- , module_()
- , name_(NULL)
- , cv_record_(NULL)
- , misc_record_(NULL)
- , debug_filename_(NULL) {
+ : MinidumpObject(minidump),
+ module_(),
+ name_(NULL),
+ cv_record_(NULL),
+ misc_record_(NULL),
+ debug_filename_(NULL) {
}
@@ -1135,10 +1135,10 @@ void MinidumpModule::Print() {
MinidumpModuleList::MinidumpModuleList(Minidump* minidump)
- : MinidumpStream(minidump)
- , range_map_()
- , modules_(NULL)
- , module_count_(0) {
+ : MinidumpStream(minidump),
+ range_map_(),
+ modules_(NULL),
+ module_count_(0) {
}
@@ -1245,11 +1245,11 @@ void MinidumpModuleList::Print() {
MinidumpMemoryList::MinidumpMemoryList(Minidump* minidump)
- : MinidumpStream(minidump)
- , range_map_()
- , descriptors_(NULL)
- , regions_(NULL)
- , region_count_(0) {
+ : MinidumpStream(minidump),
+ range_map_(),
+ descriptors_(NULL),
+ regions_(NULL),
+ region_count_(0) {
}
@@ -1387,9 +1387,9 @@ void MinidumpMemoryList::Print() {
MinidumpException::MinidumpException(Minidump* minidump)
- : MinidumpStream(minidump)
- , exception_()
- , context_(NULL) {
+ : MinidumpStream(minidump),
+ exception_(),
+ context_(NULL) {
}
@@ -1505,9 +1505,9 @@ void MinidumpException::Print() {
MinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump)
- : MinidumpStream(minidump)
- , system_info_()
- , csd_version_(NULL) {
+ : MinidumpStream(minidump),
+ system_info_(),
+ csd_version_(NULL) {
}
@@ -1619,8 +1619,8 @@ void MinidumpSystemInfo::Print() {
MinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump)
- : MinidumpStream(minidump)
- , misc_info_() {
+ : MinidumpStream(minidump),
+ misc_info_() {
}
@@ -1694,12 +1694,12 @@ void MinidumpMiscInfo::Print() {
Minidump::Minidump(int fd)
- : header_()
- , directory_(NULL)
- , stream_map_(NULL)
- , fd_(fd)
- , swap_(false)
- , valid_(false) {
+ : header_(),
+ directory_(NULL),
+ stream_map_(NULL),
+ fd_(fd),
+ swap_(false),
+ valid_(false) {
}
diff --git a/src/processor/minidump.h b/src/processor/minidump.h
index bbef1c99..8ad7c9f5 100644
--- a/src/processor/minidump.h
+++ b/src/processor/minidump.h
@@ -89,25 +89,25 @@ class Minidump;
// MinidumpObject is the base of all Minidump* objects except for Minidump
// itself.
class MinidumpObject {
- public:
- virtual ~MinidumpObject() {}
-
- protected:
- MinidumpObject(Minidump* minidump);
-
- // 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_;
-
- // 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_;
+ public:
+ virtual ~MinidumpObject() {}
+
+ protected:
+ MinidumpObject(Minidump* minidump);
+
+ // 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_;
+
+ // 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_;
};
@@ -118,21 +118,21 @@ class MinidumpObject {
// streams and adhere to the same interface, and may be derived from
// this class.
class MinidumpStream : public MinidumpObject {
- public:
- virtual ~MinidumpStream() {}
-
- protected:
- MinidumpStream(Minidump* minidump);
-
- private:
- // Populate (and validate) the MinidumpStream. minidump_ is expected
- // to be positioned at the beginning of the stream, so that the next
- // read from the minidump will be at the beginning of the stream.
- // expected_size should be set to the stream's length as contained in
- // the MDRawDirectory record or other identifying record. A class
- // that implements MinidumpStream can compare expected_size to a
- // known size as an integrity check.
- virtual bool Read(u_int32_t expected_size) = 0;
+ public:
+ virtual ~MinidumpStream() {}
+
+ protected:
+ MinidumpStream(Minidump* minidump);
+
+ private:
+ // Populate (and validate) the MinidumpStream. minidump_ is expected
+ // to be positioned at the beginning of the stream, so that the next
+ // read from the minidump will be at the beginning of the stream.
+ // expected_size should be set to the stream's length as contained in
+ // the MDRawDirectory record or other identifying record. A class
+ // that implements MinidumpStream can compare expected_size to a
+ // known size as an integrity check.
+ virtual bool Read(u_int32_t expected_size) = 0;
};
@@ -147,25 +147,24 @@ class MinidumpStream : public MinidumpObject {
// and not the context that caused the exception (which is probably what the
// user wants).
class MinidumpContext : public MinidumpStream {
- public:
- const MDRawContextX86* context() const {
- return valid_ ? &context_ : NULL; }
+ public:
+ const MDRawContextX86* context() const { return valid_ ? &context_ : NULL; }
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class MinidumpThread;
- friend class MinidumpException;
+ private:
+ friend class MinidumpThread;
+ friend class MinidumpException;
- MinidumpContext(Minidump* minidump);
+ MinidumpContext(Minidump* minidump);
- bool Read(u_int32_t expected_size);
+ bool Read(u_int32_t expected_size);
- // TODO(mmentovai): This is x86-only for now. When other CPUs are
- // supported, this class can move to MinidumpContext_x86 and derive from
- // a new abstract MinidumpContext.
- MDRawContextX86 context_;
+ // TODO(mmentovai): This is x86-only for now. When other CPUs are
+ // supported, this class can move to MinidumpContext_x86 and derive from
+ // a new abstract MinidumpContext.
+ MDRawContextX86 context_;
};
@@ -179,52 +178,52 @@ class MinidumpContext : public MinidumpStream {
// the Stackwalker family of classes.
class MinidumpMemoryRegion : public MinidumpObject,
public MemoryRegion {
- public:
- ~MinidumpMemoryRegion();
+ public:
+ ~MinidumpMemoryRegion();
- // Returns a pointer to the base of the memory region. Returns the
- // cached value if available, otherwise, reads the minidump file and
- // caches the memory region.
- const u_int8_t* GetMemory();
+ // Returns a pointer to the base of the memory region. Returns the
+ // cached value if available, otherwise, reads the minidump file and
+ // caches the memory region.
+ const u_int8_t* GetMemory();
- // The address of the base of the memory region.
- u_int64_t GetBase();
+ // The address of the base of the memory region.
+ u_int64_t GetBase();
- // The size, in bytes, of the memory region.
- u_int32_t GetSize();
+ // The size, in bytes, of the memory region.
+ u_int32_t GetSize();
- // Frees the cached memory region, if cached.
- void FreeMemory();
+ // Frees the cached memory region, if cached.
+ void FreeMemory();
- // Obtains the value of memory at the pointer specified by address.
- bool GetMemoryAtAddress(u_int64_t address, u_int8_t* value);
- bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value);
- bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value);
- bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value);
+ // Obtains the value of memory at the pointer specified by address.
+ bool GetMemoryAtAddress(u_int64_t address, u_int8_t* value);
+ bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value);
+ bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value);
+ bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value);
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class MinidumpThread;
- friend class MinidumpMemoryList;
+ private:
+ friend class MinidumpThread;
+ friend class MinidumpMemoryList;
- MinidumpMemoryRegion(Minidump* minidump);
+ 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);
+ // 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);
- // Implementation for GetMemoryAtAddress
- template<typename T> bool GetMemoryAtAddressInternal(u_int64_t address,
- T* value);
+ // Implementation for GetMemoryAtAddress
+ template<typename T> bool GetMemoryAtAddressInternal(u_int64_t address,
+ T* value);
- // Base address and size of the memory region, and its position in the
- // minidump file.
- MDMemoryDescriptor* descriptor_;
+ // Base address and size of the memory region, and its position in the
+ // minidump file.
+ MDMemoryDescriptor* descriptor_;
- // Cached memory.
- vector<u_int8_t>* memory_;
+ // Cached memory.
+ vector<u_int8_t>* memory_;
};
@@ -234,73 +233,73 @@ class MinidumpMemoryRegion : public MinidumpObject,
// MinidumpException is probably desired instead of the CPU context
// provided here.
class MinidumpThread : public MinidumpObject {
- public:
- ~MinidumpThread();
+ public:
+ ~MinidumpThread();
- const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
- MinidumpMemoryRegion* GetMemory();
- MinidumpContext* GetContext();
+ const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
+ MinidumpMemoryRegion* GetMemory();
+ 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.
- u_int32_t GetThreadID();
+ // 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.
+ u_int32_t GetThreadID();
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- // This objects are managed by MinidumpThreadList.
- friend class MinidumpThreadList;
+ private:
+ // These objects are managed by MinidumpThreadList.
+ friend class MinidumpThreadList;
- MinidumpThread(Minidump* minidump);
+ MinidumpThread(Minidump* minidump);
- // This works like MinidumpStream::Read, but is driven by
- // MinidumpThreadList. No size checking is done, because
- // MinidumpThreadList handles that directly.
- bool Read();
+ // This works like MinidumpStream::Read, but is driven by
+ // MinidumpThreadList. No size checking is done, because
+ // MinidumpThreadList handles that directly.
+ bool Read();
- MDRawThread thread_;
- MinidumpMemoryRegion* memory_;
- MinidumpContext* context_;
+ MDRawThread thread_;
+ MinidumpMemoryRegion* memory_;
+ MinidumpContext* context_;
};
// MinidumpThreadList contains all of the threads (as MinidumpThreads) in
// a process.
class MinidumpThreadList : public MinidumpStream {
- public:
- ~MinidumpThreadList();
+ public:
+ ~MinidumpThreadList();
- unsigned int thread_count() const { return valid_ ? thread_count_ : 0; }
+ unsigned int thread_count() const { return valid_ ? thread_count_ : 0; }
- // Sequential access to threads.
- MinidumpThread* GetThreadAtIndex(unsigned int index) const;
+ // Sequential access to threads.
+ MinidumpThread* GetThreadAtIndex(unsigned int index) const;
- // Random access to threads.
- MinidumpThread* GetThreadByID(u_int32_t thread_id);
+ // Random access to threads.
+ MinidumpThread* GetThreadByID(u_int32_t thread_id);
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class Minidump;
+ private:
+ friend class Minidump;
- typedef map<u_int32_t, MinidumpThread*> IDToThreadMap;
- typedef vector<MinidumpThread> MinidumpThreads;
+ typedef map<u_int32_t, MinidumpThread*> IDToThreadMap;
+ typedef vector<MinidumpThread> MinidumpThreads;
- static const u_int32_t kStreamType = THREAD_LIST_STREAM;
+ static const u_int32_t kStreamType = THREAD_LIST_STREAM;
- MinidumpThreadList(Minidump* aMinidump);
+ MinidumpThreadList(Minidump* aMinidump);
- bool Read(u_int32_t aExpectedSize);
+ bool Read(u_int32_t aExpectedSize);
- // Access to threads using the thread ID as the key.
- IDToThreadMap id_to_thread_map_;
+ // Access to threads using the thread ID as the key.
+ IDToThreadMap id_to_thread_map_;
- // The list of threads.
- MinidumpThreads* threads_;
- u_int32_t thread_count_;
+ // The list of threads.
+ MinidumpThreads* threads_;
+ u_int32_t thread_count_;
};
@@ -309,68 +308,68 @@ class MinidumpThreadList : public MinidumpStream {
// by MDRawModule, such as the module's name and a specification for where
// to locate debugging information for the module.
class MinidumpModule : public MinidumpObject {
- public:
- ~MinidumpModule();
-
- const MDRawModule* module() const { return valid_ ? &module_ : 0; }
- u_int64_t base_address() const {
- return valid_ ? module_.base_of_image : static_cast<u_int64_t>(-1); }
- u_int32_t size() const { return valid_ ? module_.size_of_image : 0; }
-
- // The name of the file containing this module's code (exe, dll, so,
- // dylib).
- const string* GetName();
-
- // The CodeView record, which contains information to locate the module's
- // debugging information (pdb). This is returned as u_int8_t* because
- // the data can be one of two types: MDCVInfoPDB20* or MDCVInfoPDB70*.
- // Check the record's signature in the first four bytes to differentiate.
- // Current toolchains generate modules which carry MDCVInfoPDB70.
- const u_int8_t* GetCVRecord();
-
- // The miscellaneous debug record, which is obsolete. Current toolchains
- // do not generate this type of debugging information (dbg), and this
- // field is not expected to be present.
- const MDImageDebugMisc* GetMiscRecord();
-
- // The filename of the file containing debugging information for this
- // module. This data is supplied by the CodeView record, if present, or
- // the miscellaneous debug record. As such, it will reference either a
- // pdb or dbg file.
- const string* GetDebugFilename();
-
- // Print a human-readable representation of the object to stdout.
- void Print();
-
- private:
- // These objects are managed by MinidumpModuleList.
- friend class MinidumpModuleList;
-
- MinidumpModule(Minidump* minidump);
-
- // This works like MinidumpStream::Read, but is driven by
- // MinidumpModuleList. No size checking is done, because
- // MinidumpModuleList handles that directly.
- bool Read();
-
- MDRawModule module_;
-
- // Cached module name.
- const string* name_;
-
- // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
- // MDCVInfoPDB70. Stored as a u_int8_t because the structure contains
- // a variable-sized string and its exact size cannot be known until it
- // is processed.
- vector<u_int8_t>* cv_record_;
-
- // Cached MDImageDebugMisc (usually not present), stored as u_int8_t
- // because the structure contains a variable-sized string and its exact
- // size cannot be known until it is processed.
- vector<u_int8_t>* misc_record_;
-
- // Cached debug filename.
- const string* debug_filename_;
+ public:
+ ~MinidumpModule();
+
+ const MDRawModule* module() const { return valid_ ? &module_ : 0; }
+ u_int64_t base_address() const {
+ return valid_ ? module_.base_of_image : static_cast<u_int64_t>(-1); }
+ u_int32_t size() const { return valid_ ? module_.size_of_image : 0; }
+
+ // The name of the file containing this module's code (exe, dll, so,
+ // dylib).
+ const string* GetName();
+
+ // The CodeView record, which contains information to locate the module's
+ // debugging information (pdb). This is returned as u_int8_t* because
+ // the data can be one of two types: MDCVInfoPDB20* or MDCVInfoPDB70*.
+ // Check the record's signature in the first four bytes to differentiate.
+ // Current toolchains generate modules which carry MDCVInfoPDB70.
+ const u_int8_t* GetCVRecord();
+
+ // The miscellaneous debug record, which is obsolete. Current toolchains
+ // do not generate this type of debugging information (dbg), and this
+ // field is not expected to be present.
+ const MDImageDebugMisc* GetMiscRecord();
+
+ // The filename of the file containing debugging information for this
+ // module. This data is supplied by the CodeView record, if present, or
+ // the miscellaneous debug record. As such, it will reference either a
+ // pdb or dbg file.
+ const string* GetDebugFilename();
+
+ // Print a human-readable representation of the object to stdout.
+ void Print();
+
+ private:
+ // These objects are managed by MinidumpModuleList.
+ friend class MinidumpModuleList;
+
+ MinidumpModule(Minidump* minidump);
+
+ // This works like MinidumpStream::Read, but is driven by
+ // MinidumpModuleList. No size checking is done, because
+ // MinidumpModuleList handles that directly.
+ bool Read();
+
+ MDRawModule module_;
+
+ // Cached module name.
+ const string* name_;
+
+ // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
+ // MDCVInfoPDB70. Stored as a u_int8_t because the structure contains
+ // a variable-sized string and its exact size cannot be known until it
+ // is processed.
+ vector<u_int8_t>* cv_record_;
+
+ // Cached MDImageDebugMisc (usually not present), stored as u_int8_t
+ // because the structure contains a variable-sized string and its exact
+ // size cannot be known until it is processed.
+ vector<u_int8_t>* misc_record_;
+
+ // Cached debug filename.
+ const string* debug_filename_;
};
@@ -379,37 +378,37 @@ class MinidumpModule : public MinidumpObject {
// so that it may easily provide a code module corresponding to a specific
// address.
class MinidumpModuleList : public MinidumpStream {
- public:
- ~MinidumpModuleList();
+ public:
+ ~MinidumpModuleList();
- unsigned int module_count() const { return valid_ ? module_count_ : 0; }
+ unsigned int module_count() const { return valid_ ? module_count_ : 0; }
- // Sequential access to modules.
- MinidumpModule* GetModuleAtIndex(unsigned int index) const;
+ // Sequential access to modules.
+ MinidumpModule* GetModuleAtIndex(unsigned int index) const;
- // Random access to modules. Returns the module whose code is present
- // at the address identified by address.
- MinidumpModule* GetModuleForAddress(u_int64_t address);
+ // Random access to modules. Returns the module whose code is present
+ // at the address identified by address.
+ MinidumpModule* GetModuleForAddress(u_int64_t address);
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class Minidump;
+ private:
+ friend class Minidump;
- typedef vector<MinidumpModule> MinidumpModules;
+ typedef vector<MinidumpModule> MinidumpModules;
- static const u_int32_t kStreamType = MODULE_LIST_STREAM;
+ static const u_int32_t kStreamType = MODULE_LIST_STREAM;
- MinidumpModuleList(Minidump* minidump);
+ MinidumpModuleList(Minidump* minidump);
- bool Read(u_int32_t expected_size);
+ bool Read(u_int32_t expected_size);
- // Access to modules using addresses as the key.
- RangeMap<u_int64_t, unsigned int> range_map_;
+ // Access to modules using addresses as the key.
+ RangeMap<u_int64_t, unsigned int> range_map_;
- MinidumpModules* modules_;
- u_int32_t module_count_;
+ MinidumpModules* modules_;
+ u_int32_t module_count_;
};
@@ -423,45 +422,45 @@ class MinidumpModuleList : public MinidumpStream {
// types of minidumps may contain significantly more memory regions. Full-
// memory minidumps contain all of a process' mapped memory.
class MinidumpMemoryList : public MinidumpStream {
- public:
- ~MinidumpMemoryList();
+ public:
+ ~MinidumpMemoryList();
- unsigned int region_count() const { return valid_ ? region_count_ : 0; }
+ unsigned int region_count() const { return valid_ ? region_count_ : 0; }
- // Sequential access to memory regions.
- MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);
+ // Sequential access to memory regions.
+ MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);
- // Random access to memory regions. Returns the region encompassing
- // the address identified by address.
- MinidumpMemoryRegion* GetMemoryRegionForAddress(u_int64_t address);
+ // Random access to memory regions. Returns the region encompassing
+ // the address identified by address.
+ MinidumpMemoryRegion* GetMemoryRegionForAddress(u_int64_t address);
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class Minidump;
+ private:
+ friend class Minidump;
- typedef vector<MDMemoryDescriptor> MemoryDescriptors;
- typedef vector<MinidumpMemoryRegion> MemoryRegions;
+ typedef vector<MDMemoryDescriptor> MemoryDescriptors;
+ typedef vector<MinidumpMemoryRegion> MemoryRegions;
- static const u_int32_t kStreamType = MEMORY_LIST_STREAM;
+ static const u_int32_t kStreamType = MEMORY_LIST_STREAM;
- MinidumpMemoryList(Minidump* minidump);
+ MinidumpMemoryList(Minidump* minidump);
- bool Read(u_int32_t expected_size);
+ bool Read(u_int32_t expected_size);
- // Access to memory regions using addresses as the key.
- RangeMap<u_int64_t, unsigned int> range_map_;
+ // Access to memory regions using addresses as the key.
+ RangeMap<u_int64_t, unsigned int> range_map_;
- // The list of descriptors. This is maintained separately from the list
- // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it
- // maintains a pointer to it. descriptors_ provides the storage for this
- // purpose.
- MemoryDescriptors* descriptors_;
+ // The list of descriptors. This is maintained separately from the list
+ // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it
+ // maintains a pointer to it. descriptors_ provides the storage for this
+ // purpose.
+ MemoryDescriptors* descriptors_;
- // The list of regions.
- MemoryRegions* regions_;
- u_int32_t region_count_;
+ // The list of regions.
+ MemoryRegions* regions_;
+ u_int32_t region_count_;
};
@@ -472,66 +471,66 @@ class MinidumpMemoryList : public MinidumpStream {
// which contains the CPU context for the exception thread at the time
// the exception occurred.
class MinidumpException : public MinidumpStream {
- public:
- ~MinidumpException();
+ public:
+ ~MinidumpException();
- const MDRawExceptionStream* exception() const {
- return valid_ ? &exception_ : 0; }
+ const MDRawExceptionStream* exception() const {
+ return valid_ ? &exception_ : 0; }
- // 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
- // MDRawExceptionStream structure.
- u_int32_t GetThreadID();
+ // 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
+ // MDRawExceptionStream structure.
+ u_int32_t GetThreadID();
- MinidumpContext* GetContext();
+ MinidumpContext* GetContext();
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class Minidump;
+ private:
+ friend class Minidump;
- static const u_int32_t kStreamType = EXCEPTION_STREAM;
+ static const u_int32_t kStreamType = EXCEPTION_STREAM;
- MinidumpException(Minidump* minidump);
+ MinidumpException(Minidump* minidump);
- bool Read(u_int32_t expected_size);
+ bool Read(u_int32_t expected_size);
- MDRawExceptionStream exception_;
- MinidumpContext* context_;
+ MDRawExceptionStream exception_;
+ MinidumpContext* context_;
};
// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about
// the system on which the minidump was generated. See also MinidumpMiscInfo.
class MinidumpSystemInfo : public MinidumpStream {
- public:
- ~MinidumpSystemInfo();
+ public:
+ ~MinidumpSystemInfo();
- const MDRawSystemInfo* system_info() const {
- return valid_ ? &system_info_ : 0; }
+ const MDRawSystemInfo* system_info() const {
+ return valid_ ? &system_info_ : 0; }
- // I don't know what CSD stands for, but this field is documented as
- // returning a textual representation of the OS service pack.
- const string* GetCSDVersion();
+ // I don't know what CSD stands for, but this field is documented as
+ // returning a textual representation of the OS service pack.
+ const string* GetCSDVersion();
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class Minidump;
+ private:
+ friend class Minidump;
- static const u_int32_t kStreamType = SYSTEM_INFO_STREAM;
+ static const u_int32_t kStreamType = SYSTEM_INFO_STREAM;
- MinidumpSystemInfo(Minidump* minidump);
+ MinidumpSystemInfo(Minidump* minidump);
- bool Read(u_int32_t expected_size);
+ bool Read(u_int32_t expected_size);
- MDRawSystemInfo system_info_;
+ MDRawSystemInfo system_info_;
- // Textual representation of the OS service pack, for minidumps produced
- // by MiniDumpWriteDump on Windows.
- const string* csd_version_;
+ // Textual representation of the OS service pack, for minidumps produced
+ // by MiniDumpWriteDump on Windows.
+ const string* csd_version_;
};
@@ -539,157 +538,141 @@ class MinidumpSystemInfo : public MinidumpStream {
// the process that generated the minidump, and optionally additional system
// information. See also MinidumpSystemInfo.
class MinidumpMiscInfo : public MinidumpStream {
- public:
- const MDRawMiscInfo* misc_info() const {
- return valid_ ? &misc_info_ : 0; }
+ public:
+ const MDRawMiscInfo* misc_info() const { return valid_ ? &misc_info_ : 0; }
- // Print a human-readable representation of the object to stdout.
- void Print();
+ // Print a human-readable representation of the object to stdout.
+ void Print();
- private:
- friend class Minidump;
+ private:
+ friend class Minidump;
- static const u_int32_t kStreamType = MISC_INFO_STREAM;
+ static const u_int32_t kStreamType = MISC_INFO_STREAM;
- MinidumpMiscInfo(Minidump* minidump_);
+ MinidumpMiscInfo(Minidump* minidump_);
- bool Read(u_int32_t expected_size_);
+ bool Read(u_int32_t expected_size_);
- MDRawMiscInfo misc_info_;
+ MDRawMiscInfo misc_info_;
};
// Minidump is the user's interface to a minidump file. It wraps MDRawHeader
// and provides access to the minidump's top-level stream directory.
class Minidump {
- public:
- // fd is a randomly seekable file descriptor that is open and is
- // positioned at the beginning of the MDRawHeader structure (byte offset
- // 0).
- Minidump(int fd);
-
- ~Minidump();
-
- const MDRawHeader* header() const { return valid_ ? &header_ : 0; }
-
- // Reads the minidump file's header and top-level stream directory.
- // The minidump is expected to be positioned at the beginning of the
- // header. Read() sets up the stream list and map, and validates the
- // Minidump object.
- bool Read();
-
- // The next 6 methods are stubs that call GetStream. They exist to
- // force code generation of the templatized API within the module, and
- // to avoid exposing an ugly API (GetStream needs to accept a garbage
- // parameter).
- MinidumpThreadList* GetThreadList();
- MinidumpModuleList* GetModuleList();
- MinidumpMemoryList* GetMemoryList();
- MinidumpException* GetException();
- MinidumpSystemInfo* GetSystemInfo();
- MinidumpMiscInfo* GetMiscInfo();
-
- // The next set of methods are provided for users who wish to access
- // data in minidump files directly, while leveraging the rest of
- // this class and related classes to handle the basic minidump
- // structure and known stream types.
-
- unsigned int GetDirectoryEntryCount() const {
- return valid_ ? header_.stream_count : 0; }
- const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;
-
- // The next 2 methods are lower-level I/O routines. They use fd_.
-
- // Reads count bytes from the minidump at the current position into
- // the storage area pointed to by bytes. bytes must be of sufficient
- // size. After the read, the file position is advanced by count.
- bool ReadBytes(void* bytes, size_t count);
-
- // Sets the position of the minidump file to offset.
- bool SeekSet(off_t offset);
-
- // The next 2 methods are medium-level I/O routines.
-
- // ReadString returns a string which is owned by the caller! offset
- // specifies the offset that a length-encoded string is stored at in the
- // minidump file.
- string* ReadString(off_t offset);
-
- // SeekToStreamType positions the file at the beginning of a stream
- // identified by stream_type, and informs the caller of the stream's
- // length by setting *stream_length. Because stream_map maps each stream
- // type to only one stream in the file, this might mislead the user into
- // thinking that the stream that this seeks to is the only stream with
- // type stream_type. That can't happen for streams that these classes
- // deal with directly, because they're only supposed to be present in the
- // file singly, and that's verified when stream_map_ is built. Users who
- // are looking for other stream types should be aware of this
- // possibility, and consider using GetDirectoryEntryAtIndex (possibly
- // with GetDirectoryEntryCount) if expecting multiple streams of the same
- // type in a single minidump file.
- bool SeekToStreamType(u_int32_t stream_type, u_int32_t* stream_length);
-
- // Print a human-readable representation of the object to stdout.
- void Print();
-
- private:
- // These classes are friends to give them access to this class' file
- // I/O utility routines.
- friend class MinidumpContext;
- friend class MinidumpMemoryRegion;
- friend class MinidumpThread;
- friend class MinidumpThreadList;
- friend class MinidumpModule;
- friend class MinidumpModuleList;
- friend class MinidumpMemoryList;
- friend class MinidumpException;
- friend class MinidumpSystemInfo;
- friend class MinidumpMiscInfo;
-
- // MinidumpStreamInfo is used in the MinidumpStreamMap. It lets
- // the Minidump object locate interesting streams quickly, and
- // provides a convenient place to stash MinidumpStream objects.
- struct MinidumpStreamInfo {
- MinidumpStreamInfo()
- : stream_index(0)
- , stream(NULL) {}
- ~MinidumpStreamInfo() { delete stream; }
-
- // Index into the MinidumpDirectoryEntries vector
- unsigned int stream_index;
-
- // Pointer to the stream if cached, or NULL if not yet populated
- MinidumpStream* stream;
- };
-
- typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
- typedef map<u_int32_t, MinidumpStreamInfo> MinidumpStreamMap;
-
- bool swap() const { return valid_ ? swap_ : false; }
-
- template<typename T> T* GetStream(T** stream);
-
- MDRawHeader header_;
-
- // The list of streams.
- MinidumpDirectoryEntries* directory_;
-
- // Access to streams using the stream type as the key.
- MinidumpStreamMap* stream_map_;
-
- // The file descriptor for all file I/O. Used by ReadBytes and SeekSet.
- int fd_;
-
- // swap_ is true if the minidump file should be byte-swapped. If the
- // minidump was produced by a CPU that is other-endian than the CPU
- // processing the minidump, this will be true. If the two CPUs are
- // same-endian, this will be false.
- bool swap_;
-
- // Validity of the Minidump structure, false immediately after
- // construction or after a failed Read(); true following a successful
- // Read().
- bool valid_;
+ public:
+ // fd is a randomly seekable file descriptor that is open and is
+ // positioned at the beginning of the MDRawHeader structure (byte offset
+ // 0).
+ Minidump(int fd);
+
+ ~Minidump();
+
+ const MDRawHeader* header() const { return valid_ ? &header_ : 0; }
+
+ // Reads the minidump file's header and top-level stream directory.
+ // The minidump is expected to be positioned at the beginning of the
+ // header. Read() sets up the stream list and map, and validates the
+ // Minidump object.
+ bool Read();
+
+ // The next 6 methods are stubs that call GetStream. They exist to
+ // force code generation of the templatized API within the module, and
+ // to avoid exposing an ugly API (GetStream needs to accept a garbage
+ // parameter).
+ MinidumpThreadList* GetThreadList();
+ MinidumpModuleList* GetModuleList();
+ MinidumpMemoryList* GetMemoryList();
+ MinidumpException* GetException();
+ MinidumpSystemInfo* GetSystemInfo();
+ MinidumpMiscInfo* GetMiscInfo();
+
+ // The next set of methods are provided for users who wish to access
+ // data in minidump files directly, while leveraging the rest of
+ // this class and related classes to handle the basic minidump
+ // structure and known stream types.
+
+ unsigned int GetDirectoryEntryCount() const {
+ return valid_ ? header_.stream_count : 0; }
+ const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;
+
+ // The next 2 methods are lower-level I/O routines. They use fd_.
+
+ // Reads count bytes from the minidump at the current position into
+ // the storage area pointed to by bytes. bytes must be of sufficient
+ // size. After the read, the file position is advanced by count.
+ bool ReadBytes(void* bytes, size_t count);
+
+ // Sets the position of the minidump file to offset.
+ bool SeekSet(off_t offset);
+
+ // The next 2 methods are medium-level I/O routines.
+
+ // ReadString returns a string which is owned by the caller! offset
+ // specifies the offset that a length-encoded string is stored at in the
+ // minidump file.
+ string* ReadString(off_t offset);
+
+ // SeekToStreamType positions the file at the beginning of a stream
+ // identified by stream_type, and informs the caller of the stream's
+ // length by setting *stream_length. Because stream_map maps each stream
+ // type to only one stream in the file, this might mislead the user into
+ // thinking that the stream that this seeks to is the only stream with
+ // type stream_type. That can't happen for streams that these classes
+ // deal with directly, because they're only supposed to be present in the
+ // file singly, and that's verified when stream_map_ is built. Users who
+ // are looking for other stream types should be aware of this
+ // possibility, and consider using GetDirectoryEntryAtIndex (possibly
+ // with GetDirectoryEntryCount) if expecting multiple streams of the same
+ // type in a single minidump file.
+ bool SeekToStreamType(u_int32_t stream_type, u_int32_t* stream_length);
+
+ bool swap() const { return valid_ ? swap_ : false; }
+
+ // Print a human-readable representation of the object to stdout.
+ void Print();
+
+ private:
+ // MinidumpStreamInfo is used in the MinidumpStreamMap. It lets
+ // the Minidump object locate interesting streams quickly, and
+ // provides a convenient place to stash MinidumpStream objects.
+ struct MinidumpStreamInfo {
+ MinidumpStreamInfo() : stream_index(0), stream(NULL) {}
+ ~MinidumpStreamInfo() { delete stream; }
+
+ // Index into the MinidumpDirectoryEntries vector
+ unsigned int stream_index;
+
+ // Pointer to the stream if cached, or NULL if not yet populated
+ MinidumpStream* stream;
+ };
+
+ typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
+ typedef map<u_int32_t, MinidumpStreamInfo> MinidumpStreamMap;
+
+ template<typename T> T* GetStream(T** stream);
+
+ MDRawHeader header_;
+
+ // The list of streams.
+ MinidumpDirectoryEntries* directory_;
+
+ // Access to streams using the stream type as the key.
+ MinidumpStreamMap* stream_map_;
+
+ // The file descriptor for all file I/O. Used by ReadBytes and SeekSet.
+ int fd_;
+
+ // swap_ is true if the minidump file should be byte-swapped. If the
+ // minidump was produced by a CPU that is other-endian than the CPU
+ // processing the minidump, this will be true. If the two CPUs are
+ // same-endian, this will be false.
+ bool swap_;
+
+ // Validity of the Minidump structure, false immediately after
+ // construction or after a failed Read(); true following a successful
+ // Read().
+ bool valid_;
};
diff --git a/src/processor/range_map.h b/src/processor/range_map.h
index a55efb13..c693aa6e 100644
--- a/src/processor/range_map.h
+++ b/src/processor/range_map.h
@@ -37,50 +37,50 @@ using std::map;
template<typename AddressType, typename EntryType>
class RangeMap {
- public:
- RangeMap() : map_() {}
-
- // Inserts a range into the map. Returns false for a parameter error,
- // or if the location of the range would conflict with a range already
- // stored in the map.
- bool StoreRange(const AddressType& base,
- const AddressType& size,
- const EntryType& entry);
-
- // Locates the range encompassing the supplied address. If there is
- // no such range, or if there is a parameter error, returns false.
- bool RetrieveRange(const AddressType& address, EntryType* entry);
-
- // Empties the range map, restoring it to the state it was when it was
- // initially created.
- void Clear();
-
- private:
- class Range {
- public:
- Range(const AddressType& base, const EntryType& entry)
- : base_(base), entry_(entry) {}
-
- AddressType base() const { return base_; }
- EntryType entry() const { return entry_; }
-
- private:
- // The base address of the range. The high address does not need to
- // be stored, because RangeMap uses it as the key to the map.
- const AddressType base_;
-
- // The entry, owned by the Range object.
- const EntryType entry_;
- };
-
- typedef map<AddressType, Range> AddressToRangeMap;
-
- // Can't depend on implicit typenames in a template
- typedef typename AddressToRangeMap::const_iterator const_iterator;
- typedef typename AddressToRangeMap::value_type value_type;
-
- // Maps the high address of each range to a EntryType.
- AddressToRangeMap map_;
+ public:
+ RangeMap() : map_() {}
+
+ // Inserts a range into the map. Returns false for a parameter error,
+ // or if the location of the range would conflict with a range already
+ // stored in the map.
+ bool StoreRange(const AddressType& base,
+ const AddressType& size,
+ const EntryType& entry);
+
+ // Locates the range encompassing the supplied address. If there is
+ // no such range, or if there is a parameter error, returns false.
+ bool RetrieveRange(const AddressType& address, EntryType* entry);
+
+ // Empties the range map, restoring it to the state it was when it was
+ // initially created.
+ void Clear();
+
+ private:
+ class Range {
+ public:
+ Range(const AddressType& base, const EntryType& entry)
+ : base_(base), entry_(entry) {}
+
+ AddressType base() const { return base_; }
+ EntryType entry() const { return entry_; }
+
+ private:
+ // The base address of the range. The high address does not need to
+ // be stored, because RangeMap uses it as the key to the map.
+ const AddressType base_;
+
+ // The entry, owned by the Range object.
+ const EntryType entry_;
+ };
+
+ typedef map<AddressType, Range> AddressToRangeMap;
+
+ // Can't depend on implicit typenames in a template
+ typedef typename AddressToRangeMap::const_iterator const_iterator;
+ typedef typename AddressToRangeMap::value_type value_type;
+
+ // Maps the high address of each range to a EntryType.
+ AddressToRangeMap map_;
};
diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc
index f81bcdf7..cd2069de 100644
--- a/src/processor/range_map_unittest.cc
+++ b/src/processor/range_map_unittest.cc
@@ -32,17 +32,17 @@ using google_airbag::RangeMap;
// A CountedObject holds an int. A global (not thread safe!) count of
// allocated CountedObjects is maintained to help test memory management.
class CountedObject {
- public:
- CountedObject(int id) : id_(id) { ++count_; }
- CountedObject(const CountedObject& that) : id_(that.id_) { ++count_; }
- ~CountedObject() { --count_; }
+ public:
+ CountedObject(int id) : id_(id) { ++count_; }
+ CountedObject(const CountedObject& that) : id_(that.id_) { ++count_; }
+ ~CountedObject() { --count_; }
- static int count() { return count_; }
- int id() const { return id_; }
+ static int count() { return count_; }
+ int id() const { return id_; }
- private:
- static int count_;
- int id_;
+ private:
+ static int count_;
+ int id_;
};
int CountedObject::count_;
@@ -210,7 +210,7 @@ bool RunTests() {
{ 20000, 20000, 34, true }, // > 8-bit
{ 0x10001, 0x10001, 35, true }, // > 16-bit
- { 27, -1, 36, false } // tests high < base
+ { 27, -1, 36, false } // tests high < base
};
// Attempt to fill the entire space. The entire space must be filled with
@@ -254,7 +254,7 @@ bool RunTests() {
{ range_tests_1, sizeof(range_tests_1) / sizeof(RangeTest) },
{ range_tests_2, sizeof(range_tests_2) / sizeof(RangeTest) },
{ range_tests_3, sizeof(range_tests_3) / sizeof(RangeTest) },
- { range_tests_0, sizeof(range_tests_0) / sizeof(RangeTest) } // Run again
+ { range_tests_0, sizeof(range_tests_0) / sizeof(RangeTest) } // Run again
};
// Maintain the range map in a pointer so that deletion can be meaningfully
diff --git a/src/processor/stackwalker.h b/src/processor/stackwalker.h
index 1ae9a85d..96e993e7 100644
--- a/src/processor/stackwalker.h
+++ b/src/processor/stackwalker.h
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// stackwalker.cc: Generic stackwalker.
+// stackwalker.h: Generic stackwalker.
//
// The Stackwalker class is an abstract base class providing common generic
// methods that apply to stacks from all systems. Specific implementations
@@ -39,41 +39,41 @@ class MinidumpModuleList;
class Stackwalker {
- public:
- virtual ~Stackwalker() {}
-
- // Produces a vector of StackFrames by calling GetContextFrame and
- // GetCallerFrame, and populating the returned frames with module
- // offset and name information if possible. The caller takes ownership
- // of the StackFrames object and is responsible for freeing it.
- StackFrames* Walk();
-
- protected:
- // memory identifies a MemoryRegion that provides the stack memory
- // for the stack to walk. modules, if non-NULL, is a MinidumpModuleList
- // that is used to look up which code module each stack frame is
- // associated with.
- Stackwalker(MemoryRegion* memory, MinidumpModuleList* modules);
-
- // The stack memory to walk. Subclasses will require this region to
- // get information from the stack.
- MemoryRegion* memory_;
-
- private:
- // Obtains the context frame, the innermost called procedure in a stack
- // trace. Returns false on failure.
- virtual bool GetContextFrame(StackFrame* frame) = 0;
-
- // Obtains a caller frame. Each call to GetCallerFrame should return the
- // frame that called the last frame returned by GetContextFrame or
- // GetCallerFrame. GetCallerFrame should return false on failure or
- // when there are no more caller frames (when the end of the stack has
- // been reached).
- virtual bool GetCallerFrame(StackFrame* frame) = 0;
-
- // A list of modules, for populating each StackFrame's module information.
- // This field is optional and may be NULL.
- MinidumpModuleList* modules_;
+ public:
+ virtual ~Stackwalker() {}
+
+ // Produces a vector of StackFrames by calling GetContextFrame and
+ // GetCallerFrame, and populating the returned frames with module
+ // offset and name information if possible. The caller takes ownership
+ // of the StackFrames object and is responsible for freeing it.
+ StackFrames* Walk();
+
+ protected:
+ // memory identifies a MemoryRegion that provides the stack memory
+ // for the stack to walk. modules, if non-NULL, is a MinidumpModuleList
+ // that is used to look up which code module each stack frame is
+ // associated with.
+ Stackwalker(MemoryRegion* memory, MinidumpModuleList* modules);
+
+ // The stack memory to walk. Subclasses will require this region to
+ // get information from the stack.
+ MemoryRegion* memory_;
+
+ private:
+ // Obtains the context frame, the innermost called procedure in a stack
+ // trace. Returns false on failure.
+ virtual bool GetContextFrame(StackFrame* frame) = 0;
+
+ // Obtains a caller frame. Each call to GetCallerFrame should return the
+ // frame that called the last frame returned by GetContextFrame or
+ // GetCallerFrame. GetCallerFrame should return false on failure or
+ // when there are no more caller frames (when the end of the stack has
+ // been reached).
+ virtual bool GetCallerFrame(StackFrame* frame) = 0;
+
+ // A list of modules, for populating each StackFrame's module information.
+ // This field is optional and may be NULL.
+ MinidumpModuleList* modules_;
};
diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc
index d3360caf..4e43c6ff 100644
--- a/src/processor/stackwalker_x86.cc
+++ b/src/processor/stackwalker_x86.cc
@@ -29,8 +29,8 @@ namespace google_airbag {
StackwalkerX86::StackwalkerX86(MinidumpContext* context,
MemoryRegion* memory,
MinidumpModuleList* modules)
- : Stackwalker(memory, modules)
- , last_frame_pointer_(0) {
+ : Stackwalker(memory, modules),
+ last_frame_pointer_(0) {
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
// The x86 is a 32-bit CPU, the limits of the supplied stack are invalid.
// Mark memory_ = NULL, which will cause stackwalking to fail.
diff --git a/src/processor/stackwalker_x86.h b/src/processor/stackwalker_x86.h
index 6bb819de..6e0225b4 100644
--- a/src/processor/stackwalker_x86.h
+++ b/src/processor/stackwalker_x86.h
@@ -37,28 +37,28 @@ class MinidumpModuleList;
class StackwalkerX86 : public Stackwalker {
- public:
- // context is a MinidumpContext object that gives access to x86-specific
- // register state corresponding to the innermost called frame to be
- // included in the stack. memory and modules are passed directly through
- // to the base Stackwalker constructor.
- StackwalkerX86(MinidumpContext* context,
- MemoryRegion* memory,
- MinidumpModuleList* modules);
-
- private:
- // Implementation of Stackwalker, using x86 context (%ebp, %eip) and
- // stack conventions (saved %ebp at [%ebp], saved %eip at 4[%ebp]).
- virtual bool GetContextFrame(StackFrame* frame);
- virtual bool GetCallerFrame(StackFrame* frame);
-
- // Stores the CPU context corresponding to the innermost stack frame to
- // be returned by GetContextFrame.
- const MDRawContextX86* context_;
-
- // Stores the frame pointer returned in the last stack frame returned by
- // GetContextFrame or GetCallerFrame.
- u_int32_t last_frame_pointer_;
+ public:
+ // context is a MinidumpContext object that gives access to x86-specific
+ // register state corresponding to the innermost called frame to be
+ // included in the stack. memory and modules are passed directly through
+ // to the base Stackwalker constructor.
+ StackwalkerX86(MinidumpContext* context,
+ MemoryRegion* memory,
+ MinidumpModuleList* modules);
+
+ private:
+ // Implementation of Stackwalker, using x86 context (%ebp, %eip) and
+ // stack conventions (saved %ebp at [%ebp], saved %eip at 4[%ebp]).
+ virtual bool GetContextFrame(StackFrame* frame);
+ virtual bool GetCallerFrame(StackFrame* frame);
+
+ // Stores the CPU context corresponding to the innermost stack frame to
+ // be returned by GetContextFrame.
+ const MDRawContextX86* context_;
+
+ // Stores the frame pointer returned in the last stack frame returned by
+ // GetContextFrame or GetCallerFrame.
+ u_int32_t last_frame_pointer_;
};