mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-28 03:54:19 +01:00
Communicate OS and CPU to SymbolSupplier (#107). r=bryner
Interface change: moved a few fields around in ProcessState; added new arguments to Stackwalker and SymbolSupplier. http://groups.google.com/group/airbag-dev/browse_thread/thread/17e4a48ec3ede932 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@101 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
0ec76c7fad
commit
97d392dc4b
@ -64,6 +64,7 @@ src_libairbag_la_SOURCES = \
|
|||||||
src/google_airbag/processor/stack_frame_cpu.h \
|
src/google_airbag/processor/stack_frame_cpu.h \
|
||||||
src/google_airbag/processor/stackwalker.h \
|
src/google_airbag/processor/stackwalker.h \
|
||||||
src/google_airbag/processor/symbol_supplier.h \
|
src/google_airbag/processor/symbol_supplier.h \
|
||||||
|
src/google_airbag/processor/system_info.h \
|
||||||
src/processor/address_map.h \
|
src/processor/address_map.h \
|
||||||
src/processor/address_map-inl.h \
|
src/processor/address_map-inl.h \
|
||||||
src/processor/basic_code_module.h \
|
src/processor/basic_code_module.h \
|
||||||
|
13
Makefile.in
13
Makefile.in
@ -282,6 +282,7 @@ EGREP = @EGREP@
|
|||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
F77 = @F77@
|
F77 = @F77@
|
||||||
FFLAGS = @FFLAGS@
|
FFLAGS = @FFLAGS@
|
||||||
|
GREP = @GREP@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
@ -309,12 +310,9 @@ SET_MAKE = @SET_MAKE@
|
|||||||
SHELL = @SHELL@
|
SHELL = @SHELL@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
VERSION = @VERSION@
|
VERSION = @VERSION@
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
ac_ct_CC = @ac_ct_CC@
|
||||||
ac_ct_CXX = @ac_ct_CXX@
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
ac_ct_F77 = @ac_ct_F77@
|
ac_ct_F77 = @ac_ct_F77@
|
||||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
|
||||||
ac_ct_STRIP = @ac_ct_STRIP@
|
|
||||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||||
@ -331,23 +329,30 @@ build_cpu = @build_cpu@
|
|||||||
build_os = @build_os@
|
build_os = @build_os@
|
||||||
build_vendor = @build_vendor@
|
build_vendor = @build_vendor@
|
||||||
datadir = @datadir@
|
datadir = @datadir@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
|
||||||
|
dvidir = @dvidir@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
host = @host@
|
host = @host@
|
||||||
host_alias = @host_alias@
|
host_alias = @host_alias@
|
||||||
host_cpu = @host_cpu@
|
host_cpu = @host_cpu@
|
||||||
host_os = @host_os@
|
host_os = @host_os@
|
||||||
host_vendor = @host_vendor@
|
host_vendor = @host_vendor@
|
||||||
|
htmldir = @htmldir@
|
||||||
includedir = @includedir@
|
includedir = @includedir@
|
||||||
infodir = @infodir@
|
infodir = @infodir@
|
||||||
install_sh = @install_sh@
|
install_sh = @install_sh@
|
||||||
libdir = @libdir@
|
libdir = @libdir@
|
||||||
libexecdir = @libexecdir@
|
libexecdir = @libexecdir@
|
||||||
|
localedir = @localedir@
|
||||||
localstatedir = @localstatedir@
|
localstatedir = @localstatedir@
|
||||||
mandir = @mandir@
|
mandir = @mandir@
|
||||||
mkdir_p = @mkdir_p@
|
mkdir_p = @mkdir_p@
|
||||||
oldincludedir = @oldincludedir@
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
program_transform_name = @program_transform_name@
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
sbindir = @sbindir@
|
sbindir = @sbindir@
|
||||||
sharedstatedir = @sharedstatedir@
|
sharedstatedir = @sharedstatedir@
|
||||||
sysconfdir = @sysconfdir@
|
sysconfdir = @sysconfdir@
|
||||||
@ -355,7 +360,6 @@ target_alias = @target_alias@
|
|||||||
|
|
||||||
# This allows #includes to be relative to src/
|
# This allows #includes to be relative to src/
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||||
docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
|
|
||||||
dist_doc_DATA = \
|
dist_doc_DATA = \
|
||||||
AUTHORS \
|
AUTHORS \
|
||||||
COPYING \
|
COPYING \
|
||||||
@ -380,6 +384,7 @@ src_libairbag_la_SOURCES = \
|
|||||||
src/google_airbag/processor/stack_frame_cpu.h \
|
src/google_airbag/processor/stack_frame_cpu.h \
|
||||||
src/google_airbag/processor/stackwalker.h \
|
src/google_airbag/processor/stackwalker.h \
|
||||||
src/google_airbag/processor/symbol_supplier.h \
|
src/google_airbag/processor/symbol_supplier.h \
|
||||||
|
src/google_airbag/processor/system_info.h \
|
||||||
src/processor/address_map.h \
|
src/processor/address_map.h \
|
||||||
src/processor/address_map-inl.h \
|
src/processor/address_map-inl.h \
|
||||||
src/processor/basic_code_module.h \
|
src/processor/basic_code_module.h \
|
||||||
|
@ -569,6 +569,15 @@ class MinidumpSystemInfo : public MinidumpStream {
|
|||||||
return valid_ ? &system_info_ : NULL;
|
return valid_ ? &system_info_ : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOS and GetCPU return textual representations of the operating system
|
||||||
|
// and CPU that produced the minidump. Unlike most other Minidump* methods,
|
||||||
|
// they return string objects, not weak pointers. Defined values for
|
||||||
|
// GetOS() are "mac", "windows", and "linux". Defined values for GetCPU
|
||||||
|
// are "x86" and "ppc". These methods return an empty string when their
|
||||||
|
// values are unknown.
|
||||||
|
string GetOS();
|
||||||
|
string GetCPU();
|
||||||
|
|
||||||
// I don't know what CSD stands for, but this field is documented as
|
// I don't know what CSD stands for, but this field is documented as
|
||||||
// returning a textual representation of the OS service pack. On other
|
// returning a textual representation of the OS service pack. On other
|
||||||
// platforms, this provides additional information about an OS version
|
// platforms, this provides additional information about an OS version
|
||||||
|
@ -40,6 +40,7 @@ class Minidump;
|
|||||||
class ProcessState;
|
class ProcessState;
|
||||||
class SourceLineResolverInterface;
|
class SourceLineResolverInterface;
|
||||||
class SymbolSupplier;
|
class SymbolSupplier;
|
||||||
|
class SystemInfo;
|
||||||
|
|
||||||
class MinidumpProcessor {
|
class MinidumpProcessor {
|
||||||
public:
|
public:
|
||||||
@ -60,19 +61,15 @@ class MinidumpProcessor {
|
|||||||
ProcessResult Process(const string &minidump_file,
|
ProcessResult Process(const string &minidump_file,
|
||||||
ProcessState *process_state);
|
ProcessState *process_state);
|
||||||
|
|
||||||
// Returns a textual representation of the base CPU type that the minidump
|
// Populates the cpu_* fields of the |info| parameter with textual
|
||||||
// in dump was produced on. Returns an empty string if this information
|
// representations of the CPU type that the minidump in |dump| was
|
||||||
// cannot be determined. If cpu_info is non-NULL, it will be set to
|
// produced on.
|
||||||
// contain additional identifying information about the CPU, or it will
|
static void GetCPUInfo(Minidump *dump, SystemInfo *info);
|
||||||
// be set empty if additional information cannot be determined.
|
|
||||||
static string GetCPUInfo(Minidump *dump, string *cpu_info);
|
|
||||||
|
|
||||||
// Returns a textual representation of the operating system that the
|
// Populates the os_* fields of the |info| parameter with textual
|
||||||
// minidump in dump was produced on. Returns an empty string if this
|
// representations of the operating system that the minidump in |dump|
|
||||||
// information cannot be determined. If os_version is non-NULL, it
|
// was produced on.
|
||||||
// will be set to contain information about the specific version of the
|
static void GetOSInfo(Minidump *dump, SystemInfo *info);
|
||||||
// OS, or it will be set empty if version information cannot be determined.
|
|
||||||
static string GetOSInfo(Minidump *dump, string *os_version);
|
|
||||||
|
|
||||||
// Returns a textual representation of the reason that a crash occurred,
|
// Returns a textual representation of the reason that a crash occurred,
|
||||||
// if the minidump in dump was produced as a result of a crash. Returns
|
// if the minidump in dump was produced as a result of a crash. Returns
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "google_airbag/processor/system_info.h"
|
||||||
|
|
||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
|
|
||||||
@ -60,10 +61,7 @@ class ProcessState {
|
|||||||
u_int64_t crash_address() const { return crash_address_; }
|
u_int64_t crash_address() const { return crash_address_; }
|
||||||
int requesting_thread() const { return requesting_thread_; }
|
int requesting_thread() const { return requesting_thread_; }
|
||||||
const vector<CallStack*>* threads() const { return &threads_; }
|
const vector<CallStack*>* threads() const { return &threads_; }
|
||||||
string os() const { return os_; }
|
const SystemInfo* system_info() const { return &system_info_; }
|
||||||
string os_version() const { return os_version_; }
|
|
||||||
string cpu() const { return cpu_; }
|
|
||||||
string cpu_info() const { return cpu_info_; }
|
|
||||||
const CodeModules* modules() const { return modules_; }
|
const CodeModules* modules() const { return modules_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -103,28 +101,8 @@ class ProcessState {
|
|||||||
// thread) at the time of the crash.
|
// thread) at the time of the crash.
|
||||||
vector<CallStack*> threads_;
|
vector<CallStack*> threads_;
|
||||||
|
|
||||||
// A string identifying the operating system, such as "Windows NT",
|
// OS and CPU information.
|
||||||
// "Mac OS X", or "Linux". If the information is present in the dump but
|
SystemInfo system_info_;
|
||||||
// its value is unknown, this field will contain a numeric value. If
|
|
||||||
// the information is not present in the dump, this field will be empty.
|
|
||||||
string os_;
|
|
||||||
|
|
||||||
// A string identifying the version of the operating system, such as
|
|
||||||
// "5.1.2600 Service Pack 2" or "10.4.8 8L2127". If the dump does not
|
|
||||||
// contain this information, this field will be empty.
|
|
||||||
string os_version_;
|
|
||||||
|
|
||||||
// A string identifying the basic CPU family, such as "x86" or "ppc".
|
|
||||||
// If this information is present in the dump but its value is unknown,
|
|
||||||
// this field will contain a numeric value. If the information is not
|
|
||||||
// present in the dump, this field will be empty.
|
|
||||||
string cpu_;
|
|
||||||
|
|
||||||
// A string further identifying the specific CPU, such as
|
|
||||||
// "GenuineIntel level 6 model 13 stepping 8". If the information is not
|
|
||||||
// present in the dump, or additional identifying information is not
|
|
||||||
// defined for the CPU family, this field will be empty.
|
|
||||||
string cpu_info_;
|
|
||||||
|
|
||||||
// The modules that were loaded into the process represented by the
|
// The modules that were loaded into the process represented by the
|
||||||
// ProcessState.
|
// ProcessState.
|
||||||
@ -133,4 +111,4 @@ class ProcessState {
|
|||||||
|
|
||||||
} // namespace google_airbag
|
} // namespace google_airbag
|
||||||
|
|
||||||
#endif // GOOGLE_AIRBAG_PROCESSOR_CALL_STACK_H__
|
#endif // GOOGLE_AIRBAG_PROCESSOR_PROCESS_STATE_H__
|
||||||
|
@ -54,6 +54,7 @@ class SourceLineResolverInterface;
|
|||||||
struct StackFrame;
|
struct StackFrame;
|
||||||
struct StackFrameInfo;
|
struct StackFrameInfo;
|
||||||
class SymbolSupplier;
|
class SymbolSupplier;
|
||||||
|
class SystemInfo;
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
@ -71,13 +72,15 @@ class Stackwalker {
|
|||||||
// Returns a new concrete subclass suitable for the CPU that a stack was
|
// Returns a new concrete subclass suitable for the CPU that a stack was
|
||||||
// generated on, according to the CPU type indicated by the context
|
// generated on, according to the CPU type indicated by the context
|
||||||
// argument. If no suitable concrete subclass exists, returns NULL.
|
// argument. If no suitable concrete subclass exists, returns NULL.
|
||||||
static Stackwalker* StackwalkerForCPU(MinidumpContext *context,
|
static Stackwalker* StackwalkerForCPU(const SystemInfo *system_info,
|
||||||
|
MinidumpContext *context,
|
||||||
MemoryRegion *memory,
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
SourceLineResolverInterface *resolver);
|
SourceLineResolverInterface *resolver);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// system_info identifies the operating system, NULL or empty if unknown.
|
||||||
// memory identifies a MemoryRegion that provides the stack memory
|
// memory identifies a MemoryRegion that provides the stack memory
|
||||||
// for the stack to walk. modules, if non-NULL, is a CodeModules
|
// for the stack to walk. modules, if non-NULL, is a CodeModules
|
||||||
// object that is used to look up which code module each stack frame is
|
// object that is used to look up which code module each stack frame is
|
||||||
@ -86,11 +89,16 @@ class Stackwalker {
|
|||||||
// resolved. resolver is an instance of SourceLineResolverInterface
|
// resolved. resolver is an instance of SourceLineResolverInterface
|
||||||
// (see source_line_resolver_interface.h and basic_source_line_resolver.h).
|
// (see source_line_resolver_interface.h and basic_source_line_resolver.h).
|
||||||
// If resolver is NULL, source line info will not be resolved.
|
// If resolver is NULL, source line info will not be resolved.
|
||||||
Stackwalker(MemoryRegion *memory,
|
Stackwalker(const SystemInfo *system_info,
|
||||||
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
SourceLineResolverInterface *resolver);
|
SourceLineResolverInterface *resolver);
|
||||||
|
|
||||||
|
// Information about the system that produced the minidump. Subclasses
|
||||||
|
// and the SymbolSupplier may find this information useful.
|
||||||
|
const SystemInfo *system_info_;
|
||||||
|
|
||||||
// The stack memory to walk. Subclasses will require this region to
|
// The stack memory to walk. Subclasses will require this region to
|
||||||
// get information from the stack.
|
// get information from the stack.
|
||||||
MemoryRegion *memory_;
|
MemoryRegion *memory_;
|
||||||
|
@ -39,6 +39,7 @@ namespace google_airbag {
|
|||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
class CodeModule;
|
class CodeModule;
|
||||||
|
class SystemInfo;
|
||||||
|
|
||||||
class SymbolSupplier {
|
class SymbolSupplier {
|
||||||
public:
|
public:
|
||||||
@ -57,8 +58,12 @@ class SymbolSupplier {
|
|||||||
virtual ~SymbolSupplier() {}
|
virtual ~SymbolSupplier() {}
|
||||||
|
|
||||||
// Retrieves the symbol file for the given CodeModule, placing the
|
// Retrieves the symbol file for the given CodeModule, placing the
|
||||||
// path in symbol_file if successful.
|
// path in symbol_file if successful. system_info contains strings
|
||||||
|
// identifying the operating system and CPU; SymbolSupplier may use to help
|
||||||
|
// locate the symbol file. system_info may be NULL or its fields may be
|
||||||
|
// empty if these values are unknown.
|
||||||
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
||||||
|
const SystemInfo *system_info,
|
||||||
string *symbol_file) = 0;
|
string *symbol_file) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
89
src/google_airbag/processor/system_info.h
Normal file
89
src/google_airbag/processor/system_info.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (c) 2006, 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.
|
||||||
|
|
||||||
|
// system_info.h: Information about the system that was running a program
|
||||||
|
// when a crash report was produced.
|
||||||
|
//
|
||||||
|
// Author: Mark Mentovai
|
||||||
|
|
||||||
|
#ifndef GOOGLE_AIRBAG_PROCESSOR_SYSTEM_INFO_H__
|
||||||
|
#define GOOGLE_AIRBAG_PROCESSOR_SYSTEM_INFO_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace google_airbag {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
struct SystemInfo {
|
||||||
|
public:
|
||||||
|
// Resets the SystemInfo object to its default values.
|
||||||
|
void Clear() {
|
||||||
|
os.clear();
|
||||||
|
os_short.clear();
|
||||||
|
os_version.clear();
|
||||||
|
cpu.clear();
|
||||||
|
cpu_info.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A string identifying the operating system, such as "Windows NT",
|
||||||
|
// "Mac OS X", or "Linux". If the information is present in the dump but
|
||||||
|
// its value is unknown, this field will contain a numeric value. If
|
||||||
|
// the information is not present in the dump, this field will be empty.
|
||||||
|
string os;
|
||||||
|
|
||||||
|
// A short form of the os string, using lowercase letters and no spaces,
|
||||||
|
// suitable for use in a filesystem. Possible values are "windows",
|
||||||
|
// "mac", and "linux". Empty if the information is not present in the dump
|
||||||
|
// or if the OS given by the dump is unknown. The values stored in this
|
||||||
|
// field should match those used by MinidumpSystemInfo::GetOS.
|
||||||
|
string os_short;
|
||||||
|
|
||||||
|
// A string identifying the version of the operating system, such as
|
||||||
|
// "5.1.2600 Service Pack 2" or "10.4.8 8L2127". If the dump does not
|
||||||
|
// contain this information, this field will be empty.
|
||||||
|
string os_version;
|
||||||
|
|
||||||
|
// A string identifying the basic CPU family, such as "x86" or "ppc".
|
||||||
|
// If this information is present in the dump but its value is unknown,
|
||||||
|
// this field will contain a numeric value. If the information is not
|
||||||
|
// present in the dump, this field will be empty. The values stored in
|
||||||
|
// this field should match those used by MinidumpSystemInfo::GetCPU.
|
||||||
|
string cpu;
|
||||||
|
|
||||||
|
// A string further identifying the specific CPU, such as
|
||||||
|
// "GenuineIntel level 6 model 13 stepping 8". If the information is not
|
||||||
|
// present in the dump, or additional identifying information is not
|
||||||
|
// defined for the CPU family, this field will be empty.
|
||||||
|
string cpu_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace google_airbag
|
||||||
|
|
||||||
|
#endif // GOOGLE_AIRBAG_PROCESSOR_SYSTEM_INFO_H__
|
@ -2047,6 +2047,52 @@ bool MinidumpSystemInfo::Read(u_int32_t expected_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string MinidumpSystemInfo::GetOS() {
|
||||||
|
if (!valid_)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
string os;
|
||||||
|
|
||||||
|
switch (system_info_.platform_id) {
|
||||||
|
case MD_OS_WIN32_NT:
|
||||||
|
case MD_OS_WIN32_WINDOWS:
|
||||||
|
os = "windows";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MD_OS_MAC_OS_X:
|
||||||
|
os = "mac";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MD_OS_LINUX:
|
||||||
|
os = "linux";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string MinidumpSystemInfo::GetCPU() {
|
||||||
|
if (!valid_)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
string cpu;
|
||||||
|
|
||||||
|
switch (system_info_.processor_architecture) {
|
||||||
|
case MD_CPU_ARCHITECTURE_X86:
|
||||||
|
case MD_CPU_ARCHITECTURE_X86_WIN64:
|
||||||
|
cpu = "x86";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MD_CPU_ARCHITECTURE_PPC:
|
||||||
|
cpu = "ppc";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const string* MinidumpSystemInfo::GetCSDVersion() {
|
const string* MinidumpSystemInfo::GetCSDVersion() {
|
||||||
if (!valid_)
|
if (!valid_)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -59,8 +59,8 @@ MinidumpProcessor::ProcessResult MinidumpProcessor::Process(
|
|||||||
assert(header);
|
assert(header);
|
||||||
process_state->time_date_stamp_ = header->time_date_stamp;
|
process_state->time_date_stamp_ = header->time_date_stamp;
|
||||||
|
|
||||||
process_state->cpu_ = GetCPUInfo(&dump, &process_state->cpu_info_);
|
GetCPUInfo(&dump, &process_state->system_info_);
|
||||||
process_state->os_ = GetOSInfo(&dump, &process_state->os_version_);
|
GetOSInfo(&dump, &process_state->system_info_);
|
||||||
|
|
||||||
u_int32_t dump_thread_id = 0;
|
u_int32_t dump_thread_id = 0;
|
||||||
bool has_dump_thread = false;
|
bool has_dump_thread = false;
|
||||||
@ -162,7 +162,8 @@ MinidumpProcessor::ProcessResult MinidumpProcessor::Process(
|
|||||||
// (just like the StackFrame objects), and is much more suitable for this
|
// (just like the StackFrame objects), and is much more suitable for this
|
||||||
// task.
|
// task.
|
||||||
scoped_ptr<Stackwalker> stackwalker(
|
scoped_ptr<Stackwalker> stackwalker(
|
||||||
Stackwalker::StackwalkerForCPU(context,
|
Stackwalker::StackwalkerForCPU(process_state->system_info(),
|
||||||
|
context,
|
||||||
thread_memory,
|
thread_memory,
|
||||||
process_state->modules_,
|
process_state->modules_,
|
||||||
supplier_,
|
supplier_,
|
||||||
@ -202,24 +203,25 @@ static const MDRawSystemInfo* GetSystemInfo(Minidump *dump,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
string MinidumpProcessor::GetCPUInfo(Minidump *dump, string *cpu_info) {
|
void MinidumpProcessor::GetCPUInfo(Minidump *dump, SystemInfo *info) {
|
||||||
if (cpu_info)
|
assert(dump);
|
||||||
cpu_info->clear();
|
assert(info);
|
||||||
|
|
||||||
|
info->cpu.clear();
|
||||||
|
info->cpu_info.clear();
|
||||||
|
|
||||||
MinidumpSystemInfo *system_info;
|
MinidumpSystemInfo *system_info;
|
||||||
const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
|
const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
|
||||||
if (!raw_system_info)
|
if (!raw_system_info)
|
||||||
return "";
|
return;
|
||||||
|
|
||||||
string cpu;
|
|
||||||
switch (raw_system_info->processor_architecture) {
|
switch (raw_system_info->processor_architecture) {
|
||||||
case MD_CPU_ARCHITECTURE_X86: {
|
case MD_CPU_ARCHITECTURE_X86: {
|
||||||
cpu = "x86";
|
info->cpu = "x86";
|
||||||
if (cpu_info) {
|
|
||||||
const string *cpu_vendor = system_info->GetCPUVendor();
|
const string *cpu_vendor = system_info->GetCPUVendor();
|
||||||
if (cpu_vendor) {
|
if (cpu_vendor) {
|
||||||
cpu_info->assign(*cpu_vendor);
|
info->cpu_info = *cpu_vendor;
|
||||||
cpu_info->append(" ");
|
info->cpu_info.append(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
char x86_info[36];
|
char x86_info[36];
|
||||||
@ -227,13 +229,12 @@ string MinidumpProcessor::GetCPUInfo(Minidump *dump, string *cpu_info) {
|
|||||||
raw_system_info->processor_level,
|
raw_system_info->processor_level,
|
||||||
raw_system_info->processor_revision >> 8,
|
raw_system_info->processor_revision >> 8,
|
||||||
raw_system_info->processor_revision & 0xff);
|
raw_system_info->processor_revision & 0xff);
|
||||||
cpu_info->append(x86_info);
|
info->cpu_info.append(x86_info);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MD_CPU_ARCHITECTURE_PPC: {
|
case MD_CPU_ARCHITECTURE_PPC: {
|
||||||
cpu = "ppc";
|
info->cpu = "ppc";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,43 +243,46 @@ string MinidumpProcessor::GetCPUInfo(Minidump *dump, string *cpu_info) {
|
|||||||
char cpu_string[7];
|
char cpu_string[7];
|
||||||
snprintf(cpu_string, sizeof(cpu_string), "0x%04x",
|
snprintf(cpu_string, sizeof(cpu_string), "0x%04x",
|
||||||
raw_system_info->processor_architecture);
|
raw_system_info->processor_architecture);
|
||||||
cpu = cpu_string;
|
info->cpu = cpu_string;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cpu;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
string MinidumpProcessor::GetOSInfo(Minidump *dump, string *os_version) {
|
void MinidumpProcessor::GetOSInfo(Minidump *dump, SystemInfo *info) {
|
||||||
if (os_version)
|
assert(dump);
|
||||||
os_version->clear();
|
assert(info);
|
||||||
|
|
||||||
|
info->os.clear();
|
||||||
|
info->os_short.clear();
|
||||||
|
info->os_version.clear();
|
||||||
|
|
||||||
MinidumpSystemInfo *system_info;
|
MinidumpSystemInfo *system_info;
|
||||||
const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
|
const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info);
|
||||||
if (!raw_system_info)
|
if (!raw_system_info)
|
||||||
return "";
|
return;
|
||||||
|
|
||||||
|
info->os_short = system_info->GetOS();
|
||||||
|
|
||||||
string os;
|
|
||||||
switch (raw_system_info->platform_id) {
|
switch (raw_system_info->platform_id) {
|
||||||
case MD_OS_WIN32_NT: {
|
case MD_OS_WIN32_NT: {
|
||||||
os = "Windows NT";
|
info->os = "Windows NT";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MD_OS_WIN32_WINDOWS: {
|
case MD_OS_WIN32_WINDOWS: {
|
||||||
os = "Windows";
|
info->os = "Windows";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MD_OS_MAC_OS_X: {
|
case MD_OS_MAC_OS_X: {
|
||||||
os = "Mac OS X";
|
info->os = "Mac OS X";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MD_OS_LINUX: {
|
case MD_OS_LINUX: {
|
||||||
os = "Linux";
|
info->os = "Linux";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,29 +291,25 @@ string MinidumpProcessor::GetOSInfo(Minidump *dump, string *os_version) {
|
|||||||
char os_string[11];
|
char os_string[11];
|
||||||
snprintf(os_string, sizeof(os_string), "0x%08x",
|
snprintf(os_string, sizeof(os_string), "0x%08x",
|
||||||
raw_system_info->platform_id);
|
raw_system_info->platform_id);
|
||||||
os = os_string;
|
info->os = os_string;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os_version) {
|
|
||||||
char os_version_string[33];
|
char os_version_string[33];
|
||||||
snprintf(os_version_string, sizeof(os_version_string), "%u.%u.%u",
|
snprintf(os_version_string, sizeof(os_version_string), "%u.%u.%u",
|
||||||
raw_system_info->major_version,
|
raw_system_info->major_version,
|
||||||
raw_system_info->minor_version,
|
raw_system_info->minor_version,
|
||||||
raw_system_info->build_number);
|
raw_system_info->build_number);
|
||||||
os_version->assign(os_version_string);
|
info->os_version = os_version_string;
|
||||||
|
|
||||||
const string *csd_version = system_info->GetCSDVersion();
|
const string *csd_version = system_info->GetCSDVersion();
|
||||||
if (csd_version) {
|
if (csd_version) {
|
||||||
os_version->append(" ");
|
info->os_version.append(" ");
|
||||||
os_version->append(*csd_version);
|
info->os_version.append(*csd_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
string MinidumpProcessor::GetCrashReason(Minidump *dump, u_int64_t *address) {
|
string MinidumpProcessor::GetCrashReason(Minidump *dump, u_int64_t *address) {
|
||||||
MinidumpException *exception = dump->GetException();
|
MinidumpException *exception = dump->GetException();
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
// Unit test for MinidumpProcessor. Uses a pre-generated minidump and
|
// Unit test for MinidumpProcessor. Uses a pre-generated minidump and
|
||||||
// corresponding symbol file, and checks the stack frames for correctness.
|
// corresponding symbol file, and checks the stack frames for correctness.
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "google_airbag/processor/basic_source_line_resolver.h"
|
#include "google_airbag/processor/basic_source_line_resolver.h"
|
||||||
#include "google_airbag/processor/call_stack.h"
|
#include "google_airbag/processor/call_stack.h"
|
||||||
@ -51,6 +52,14 @@ using google_airbag::MinidumpProcessor;
|
|||||||
using google_airbag::ProcessState;
|
using google_airbag::ProcessState;
|
||||||
using google_airbag::scoped_ptr;
|
using google_airbag::scoped_ptr;
|
||||||
using google_airbag::SymbolSupplier;
|
using google_airbag::SymbolSupplier;
|
||||||
|
using google_airbag::SystemInfo;
|
||||||
|
|
||||||
|
static const char *kSystemInfoOS = "Windows NT";
|
||||||
|
static const char *kSystemInfoOSShort = "windows";
|
||||||
|
static const char *kSystemInfoOSVersion = "5.1.2600 Service Pack 2";
|
||||||
|
static const char *kSystemInfoCPU = "x86";
|
||||||
|
static const char *kSystemInfoCPUInfo =
|
||||||
|
"GenuineIntel family 6 model 13 stepping 8";
|
||||||
|
|
||||||
#define ASSERT_TRUE(cond) \
|
#define ASSERT_TRUE(cond) \
|
||||||
if (!(cond)) { \
|
if (!(cond)) { \
|
||||||
@ -62,11 +71,21 @@ using google_airbag::SymbolSupplier;
|
|||||||
|
|
||||||
#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
|
#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
|
||||||
|
|
||||||
|
// Use ASSERT_*_ABORT in functions that can't return a boolean.
|
||||||
|
#define ASSERT_TRUE_ABORT(cond) \
|
||||||
|
if (!(cond)) { \
|
||||||
|
fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
|
||||||
|
abort(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_EQ_ABORT(e1, e2) ASSERT_TRUE_ABORT((e1) == (e2))
|
||||||
|
|
||||||
class TestSymbolSupplier : public SymbolSupplier {
|
class TestSymbolSupplier : public SymbolSupplier {
|
||||||
public:
|
public:
|
||||||
TestSymbolSupplier() : interrupt_(false) {}
|
TestSymbolSupplier() : interrupt_(false) {}
|
||||||
|
|
||||||
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
||||||
|
const SystemInfo *system_info,
|
||||||
string *symbol_file);
|
string *symbol_file);
|
||||||
|
|
||||||
// When set to true, causes the SymbolSupplier to return INTERRUPT
|
// When set to true, causes the SymbolSupplier to return INTERRUPT
|
||||||
@ -77,7 +96,17 @@ class TestSymbolSupplier : public SymbolSupplier {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile(
|
SymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile(
|
||||||
const CodeModule *module, string *symbol_file) {
|
const CodeModule *module,
|
||||||
|
const SystemInfo *system_info,
|
||||||
|
string *symbol_file) {
|
||||||
|
ASSERT_TRUE_ABORT(module);
|
||||||
|
ASSERT_TRUE_ABORT(system_info);
|
||||||
|
ASSERT_EQ_ABORT(system_info->cpu, kSystemInfoCPU);
|
||||||
|
ASSERT_EQ_ABORT(system_info->cpu_info, kSystemInfoCPUInfo);
|
||||||
|
ASSERT_EQ_ABORT(system_info->os, kSystemInfoOS);
|
||||||
|
ASSERT_EQ_ABORT(system_info->os_short, kSystemInfoOSShort);
|
||||||
|
ASSERT_EQ_ABORT(system_info->os_version, kSystemInfoOSVersion);
|
||||||
|
|
||||||
if (interrupt_) {
|
if (interrupt_) {
|
||||||
return INTERRUPT;
|
return INTERRUPT;
|
||||||
}
|
}
|
||||||
@ -104,10 +133,11 @@ static bool RunTests() {
|
|||||||
ProcessState state;
|
ProcessState state;
|
||||||
ASSERT_EQ(processor.Process(minidump_file, &state),
|
ASSERT_EQ(processor.Process(minidump_file, &state),
|
||||||
MinidumpProcessor::PROCESS_OK);
|
MinidumpProcessor::PROCESS_OK);
|
||||||
ASSERT_EQ(state.cpu(), "x86");
|
ASSERT_EQ(state.system_info()->os, kSystemInfoOS);
|
||||||
ASSERT_EQ(state.cpu_info(), "GenuineIntel family 6 model 13 stepping 8");
|
ASSERT_EQ(state.system_info()->os_short, kSystemInfoOSShort);
|
||||||
ASSERT_EQ(state.os(), "Windows NT");
|
ASSERT_EQ(state.system_info()->os_version, kSystemInfoOSVersion);
|
||||||
ASSERT_EQ(state.os_version(), "5.1.2600 Service Pack 2");
|
ASSERT_EQ(state.system_info()->cpu, kSystemInfoCPU);
|
||||||
|
ASSERT_EQ(state.system_info()->cpu_info, kSystemInfoCPUInfo);
|
||||||
ASSERT_TRUE(state.crashed());
|
ASSERT_TRUE(state.crashed());
|
||||||
ASSERT_EQ(state.crash_reason(), "EXCEPTION_ACCESS_VIOLATION");
|
ASSERT_EQ(state.crash_reason(), "EXCEPTION_ACCESS_VIOLATION");
|
||||||
ASSERT_EQ(state.crash_address(), 0x45);
|
ASSERT_EQ(state.crash_address(), 0x45);
|
||||||
@ -121,7 +151,8 @@ static bool RunTests() {
|
|||||||
ASSERT_TRUE(stack->frames()->at(0)->module);
|
ASSERT_TRUE(stack->frames()->at(0)->module);
|
||||||
ASSERT_EQ(stack->frames()->at(0)->module->base_address(), 0x400000);
|
ASSERT_EQ(stack->frames()->at(0)->module->base_address(), 0x400000);
|
||||||
ASSERT_EQ(stack->frames()->at(0)->module->code_file(), "C:\\test_app.exe");
|
ASSERT_EQ(stack->frames()->at(0)->module->code_file(), "C:\\test_app.exe");
|
||||||
ASSERT_EQ(stack->frames()->at(0)->function_name, "`anonymous namespace'::CrashFunction");
|
ASSERT_EQ(stack->frames()->at(0)->function_name,
|
||||||
|
"`anonymous namespace'::CrashFunction");
|
||||||
ASSERT_EQ(stack->frames()->at(0)->source_file_name, "c:\\test_app.cc");
|
ASSERT_EQ(stack->frames()->at(0)->source_file_name, "c:\\test_app.cc");
|
||||||
ASSERT_EQ(stack->frames()->at(0)->source_line, 56);
|
ASSERT_EQ(stack->frames()->at(0)->source_line, 56);
|
||||||
|
|
||||||
|
@ -206,10 +206,11 @@ static bool PrintMinidumpProcess(const string &minidump_file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print OS and CPU information.
|
// Print OS and CPU information.
|
||||||
string cpu = process_state.cpu();
|
string cpu = process_state.system_info()->cpu;
|
||||||
string cpu_info = process_state.cpu_info();
|
string cpu_info = process_state.system_info()->cpu_info;
|
||||||
printf("Operating system: %s\n", process_state.os().c_str());
|
printf("Operating system: %s\n", process_state.system_info()->os.c_str());
|
||||||
printf(" %s\n", process_state.os_version().c_str());
|
printf(" %s\n",
|
||||||
|
process_state.system_info()->os_version.c_str());
|
||||||
printf("CPU: %s\n", cpu.c_str());
|
printf("CPU: %s\n", cpu.c_str());
|
||||||
if (!cpu_info.empty()) {
|
if (!cpu_info.empty()) {
|
||||||
// This field is optional.
|
// This field is optional.
|
||||||
|
@ -55,10 +55,7 @@ void ProcessState::Clear() {
|
|||||||
delete *iterator;
|
delete *iterator;
|
||||||
}
|
}
|
||||||
threads_.clear();
|
threads_.clear();
|
||||||
os_.clear();
|
system_info_.Clear();
|
||||||
os_version_.clear();
|
|
||||||
cpu_.clear();
|
|
||||||
cpu_info_.clear();
|
|
||||||
delete modules_;
|
delete modules_;
|
||||||
modules_ = NULL;
|
modules_ = NULL;
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,14 @@
|
|||||||
|
|
||||||
#include "processor/simple_symbol_supplier.h"
|
#include "processor/simple_symbol_supplier.h"
|
||||||
#include "google_airbag/processor/code_module.h"
|
#include "google_airbag/processor/code_module.h"
|
||||||
|
#include "google_airbag/processor/system_info.h"
|
||||||
#include "processor/pathname_stripper.h"
|
#include "processor/pathname_stripper.h"
|
||||||
|
|
||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
|
|
||||||
SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetSymbolFileAtPath(
|
SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetSymbolFileAtPath(
|
||||||
const CodeModule *module, const string &root_path, string *symbol_file) {
|
const CodeModule *module, const SystemInfo *system_info,
|
||||||
|
const string &root_path, string *symbol_file) {
|
||||||
assert(symbol_file);
|
assert(symbol_file);
|
||||||
if (!module)
|
if (!module)
|
||||||
return NOT_FOUND;
|
return NOT_FOUND;
|
||||||
|
@ -94,12 +94,14 @@ class SimpleSymbolSupplier : public SymbolSupplier {
|
|||||||
// Returns the path to the symbol file for the given module. See the
|
// Returns the path to the symbol file for the given module. See the
|
||||||
// description above.
|
// description above.
|
||||||
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
||||||
|
const SystemInfo *system_info,
|
||||||
string *symbol_file) {
|
string *symbol_file) {
|
||||||
return GetSymbolFileAtPath(module, path_, symbol_file);
|
return GetSymbolFileAtPath(module, system_info, path_, symbol_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SymbolResult GetSymbolFileAtPath(const CodeModule *module,
|
SymbolResult GetSymbolFileAtPath(const CodeModule *module,
|
||||||
|
const SystemInfo *system_info,
|
||||||
const string &root_path,
|
const string &root_path,
|
||||||
string *symbol_file);
|
string *symbol_file);
|
||||||
|
|
||||||
|
@ -53,10 +53,13 @@
|
|||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
|
|
||||||
|
|
||||||
Stackwalker::Stackwalker(MemoryRegion *memory, const CodeModules *modules,
|
Stackwalker::Stackwalker(const SystemInfo *system_info,
|
||||||
|
MemoryRegion *memory,
|
||||||
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
SourceLineResolverInterface *resolver)
|
SourceLineResolverInterface *resolver)
|
||||||
: memory_(memory),
|
: system_info_(system_info),
|
||||||
|
memory_(memory),
|
||||||
modules_(modules),
|
modules_(modules),
|
||||||
supplier_(supplier),
|
supplier_(supplier),
|
||||||
resolver_(resolver) {
|
resolver_(resolver) {
|
||||||
@ -96,7 +99,7 @@ bool Stackwalker::Walk(CallStack *stack) {
|
|||||||
supplier_) {
|
supplier_) {
|
||||||
string symbol_file;
|
string symbol_file;
|
||||||
SymbolSupplier::SymbolResult symbol_result =
|
SymbolSupplier::SymbolResult symbol_result =
|
||||||
supplier_->GetSymbolFile(module, &symbol_file);
|
supplier_->GetSymbolFile(module, system_info_, &symbol_file);
|
||||||
|
|
||||||
switch (symbol_result) {
|
switch (symbol_result) {
|
||||||
case SymbolSupplier::FOUND:
|
case SymbolSupplier::FOUND:
|
||||||
@ -130,6 +133,7 @@ bool Stackwalker::Walk(CallStack *stack) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
Stackwalker* Stackwalker::StackwalkerForCPU(
|
Stackwalker* Stackwalker::StackwalkerForCPU(
|
||||||
|
const SystemInfo *system_info,
|
||||||
MinidumpContext *context,
|
MinidumpContext *context,
|
||||||
MemoryRegion *memory,
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
@ -140,13 +144,15 @@ Stackwalker* Stackwalker::StackwalkerForCPU(
|
|||||||
u_int32_t cpu = context->GetContextCPU();
|
u_int32_t cpu = context->GetContextCPU();
|
||||||
switch (cpu) {
|
switch (cpu) {
|
||||||
case MD_CONTEXT_X86:
|
case MD_CONTEXT_X86:
|
||||||
cpu_stackwalker = new StackwalkerX86(context->GetContextX86(),
|
cpu_stackwalker = new StackwalkerX86(system_info,
|
||||||
|
context->GetContextX86(),
|
||||||
memory, modules, supplier,
|
memory, modules, supplier,
|
||||||
resolver);
|
resolver);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MD_CONTEXT_PPC:
|
case MD_CONTEXT_PPC:
|
||||||
cpu_stackwalker = new StackwalkerPPC(context->GetContextPPC(),
|
cpu_stackwalker = new StackwalkerPPC(system_info,
|
||||||
|
context->GetContextPPC(),
|
||||||
memory, modules, supplier,
|
memory, modules, supplier,
|
||||||
resolver);
|
resolver);
|
||||||
break;
|
break;
|
||||||
|
@ -42,12 +42,13 @@
|
|||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
|
|
||||||
|
|
||||||
StackwalkerPPC::StackwalkerPPC(const MDRawContextPPC *context,
|
StackwalkerPPC::StackwalkerPPC(const SystemInfo *system_info,
|
||||||
|
const MDRawContextPPC *context,
|
||||||
MemoryRegion *memory,
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
SourceLineResolverInterface *resolver)
|
SourceLineResolverInterface *resolver)
|
||||||
: Stackwalker(memory, modules, supplier, resolver),
|
: Stackwalker(system_info, memory, modules, supplier, resolver),
|
||||||
context_(context) {
|
context_(context) {
|
||||||
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
|
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
|
||||||
// This implementation only covers 32-bit ppc CPUs. The limits of the
|
// This implementation only covers 32-bit ppc CPUs. The limits of the
|
||||||
|
@ -53,7 +53,8 @@ class StackwalkerPPC : public Stackwalker {
|
|||||||
// register state corresponding to the innermost called frame to be
|
// register state corresponding to the innermost called frame to be
|
||||||
// included in the stack. The other arguments are passed directly through
|
// included in the stack. The other arguments are passed directly through
|
||||||
// to the base Stackwalker constructor.
|
// to the base Stackwalker constructor.
|
||||||
StackwalkerPPC(const MDRawContextPPC *context,
|
StackwalkerPPC(const SystemInfo *system_info,
|
||||||
|
const MDRawContextPPC *context,
|
||||||
MemoryRegion *memory,
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
|
@ -227,15 +227,15 @@ static unsigned int CountCallerFrames() {
|
|||||||
context.ebp = GetEBP();
|
context.ebp = GetEBP();
|
||||||
context.esp = GetESP();
|
context.esp = GetESP();
|
||||||
|
|
||||||
StackwalkerX86 stackwalker = StackwalkerX86(&context, &memory, NULL, NULL,
|
StackwalkerX86 stackwalker = StackwalkerX86(NULL, &context, &memory, NULL,
|
||||||
&resolver);
|
NULL, &resolver);
|
||||||
#elif defined(__ppc__)
|
#elif defined(__ppc__)
|
||||||
MDRawContextPPC context = MDRawContextPPC();
|
MDRawContextPPC context = MDRawContextPPC();
|
||||||
context.srr0 = GetPC();
|
context.srr0 = GetPC();
|
||||||
context.gpr[1] = GetSP();
|
context.gpr[1] = GetSP();
|
||||||
|
|
||||||
StackwalkerPPC stackwalker = StackwalkerPPC(&context, &memory, NULL, NULL,
|
StackwalkerPPC stackwalker = StackwalkerPPC(NULL, &context, &memory, NULL,
|
||||||
&resolver);
|
NULL, &resolver);
|
||||||
#endif // __i386__ || __ppc__
|
#endif // __i386__ || __ppc__
|
||||||
|
|
||||||
CallStack stack;
|
CallStack stack;
|
||||||
|
@ -46,12 +46,13 @@
|
|||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
|
|
||||||
|
|
||||||
StackwalkerX86::StackwalkerX86(const MDRawContextX86 *context,
|
StackwalkerX86::StackwalkerX86(const SystemInfo *system_info,
|
||||||
|
const MDRawContextX86 *context,
|
||||||
MemoryRegion *memory,
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
SourceLineResolverInterface *resolver)
|
SourceLineResolverInterface *resolver)
|
||||||
: Stackwalker(memory, modules, supplier, resolver),
|
: Stackwalker(system_info, memory, modules, supplier, resolver),
|
||||||
context_(context) {
|
context_(context) {
|
||||||
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
|
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
|
||||||
// The x86 is a 32-bit CPU, the limits of the supplied stack are invalid.
|
// The x86 is a 32-bit CPU, the limits of the supplied stack are invalid.
|
||||||
|
@ -54,7 +54,8 @@ class StackwalkerX86 : public Stackwalker {
|
|||||||
// register state corresponding to the innermost called frame to be
|
// register state corresponding to the innermost called frame to be
|
||||||
// included in the stack. The other arguments are passed directly through
|
// included in the stack. The other arguments are passed directly through
|
||||||
// to the base Stackwalker constructor.
|
// to the base Stackwalker constructor.
|
||||||
StackwalkerX86(const MDRawContextX86 *context,
|
StackwalkerX86(const SystemInfo *system_info,
|
||||||
|
const MDRawContextX86 *context,
|
||||||
MemoryRegion *memory,
|
MemoryRegion *memory,
|
||||||
const CodeModules *modules,
|
const CodeModules *modules,
|
||||||
SymbolSupplier *supplier,
|
SymbolSupplier *supplier,
|
||||||
|
Loading…
Reference in New Issue
Block a user