Add crash_report tool that will:
- Generate local symbol file for module - Output minidump report in a format similar to Apple's crash reporter git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@93 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
f755a85d93
commit
b65dce60f1
4 changed files with 958 additions and 0 deletions
330
src/tools/mac/crash_report/crash_report.mm
Normal file
330
src/tools/mac/crash_report/crash_report.mm
Normal file
|
@ -0,0 +1,330 @@
|
|||
//
|
||||
// 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.
|
||||
|
||||
// crash_report.mm: Convert the contents of a minidump into a format that
|
||||
// looks more like Apple's CrashReporter format
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <mach/machine.h>
|
||||
#include <mach-o/arch.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#include "google_airbag/processor/basic_source_line_resolver.h"
|
||||
#include "google_airbag/processor/call_stack.h"
|
||||
#include "google_airbag/processor/code_module.h"
|
||||
#include "google_airbag/processor/minidump.h"
|
||||
#include "google_airbag/processor/minidump_processor.h"
|
||||
#include "google_airbag/processor/process_state.h"
|
||||
#include "google_airbag/processor/stack_frame_cpu.h"
|
||||
#include "processor/pathname_stripper.h"
|
||||
#include "processor/scoped_ptr.h"
|
||||
#include "processor/simple_symbol_supplier.h"
|
||||
|
||||
#include "on_demand_symbol_supplier.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
using google_airbag::BasicSourceLineResolver;
|
||||
using google_airbag::CallStack;
|
||||
using google_airbag::CodeModule;
|
||||
using google_airbag::CodeModules;
|
||||
using google_airbag::MinidumpProcessor;
|
||||
using google_airbag::OnDemandSymbolSupplier;
|
||||
using google_airbag::PathnameStripper;
|
||||
using google_airbag::ProcessState;
|
||||
using google_airbag::scoped_ptr;
|
||||
using google_airbag::StackFrame;
|
||||
using google_airbag::StackFramePPC;
|
||||
using google_airbag::StackFrameX86;
|
||||
|
||||
typedef struct {
|
||||
NSString *minidumpPath;
|
||||
NSString *searchDir;
|
||||
} Options;
|
||||
|
||||
//=============================================================================
|
||||
static int PrintRegister(const char *name, u_int32_t value, int sequence) {
|
||||
if (sequence % 4 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("%6s = 0x%08x ", name, value);
|
||||
return ++sequence;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
static void PrintStack(const CallStack *stack, const string &cpu) {
|
||||
int frame_count = stack->frames()->size();
|
||||
char buffer[1024];
|
||||
for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
|
||||
const StackFrame *frame = stack->frames()->at(frame_index);
|
||||
const CodeModule *module = frame->module;
|
||||
printf("%2d ", frame_index);
|
||||
|
||||
if (module) {
|
||||
// Module name (20 chars max)
|
||||
strcpy(buffer, PathnameStripper::File(module->code_file()).c_str());
|
||||
int maxStr = 20;
|
||||
buffer[maxStr] = 0;
|
||||
printf("%-*s", maxStr, buffer);
|
||||
u_int64_t instruction = frame->instruction;
|
||||
|
||||
// PPC only: Adjust the instruction to match that of Crash reporter. The
|
||||
// instruction listed is actually the return address. See the detailed
|
||||
// comments in stackwalker_ppc.cc for more information.
|
||||
if (cpu == "ppc" && frame_index)
|
||||
instruction += 4;
|
||||
|
||||
printf(" 0x%08llx ", instruction);
|
||||
|
||||
// Function name
|
||||
if (!frame->function_name.empty()) {
|
||||
printf("%s", frame->function_name.c_str());
|
||||
if (!frame->source_file_name.empty()) {
|
||||
string source_file = PathnameStripper::File(frame->source_file_name);
|
||||
printf(" + 0x%llx (%s:%d)",
|
||||
instruction - frame->source_line_base,
|
||||
source_file.c_str(), frame->source_line);
|
||||
} else {
|
||||
printf(" + 0x%llx", instruction - frame->function_base);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
static void PrintRegisters(const CallStack *stack, const string &cpu) {
|
||||
int sequence = 0;
|
||||
const StackFrame *frame = stack->frames()->at(0);
|
||||
if (cpu == "x86") {
|
||||
const StackFrameX86 *frame_x86 =
|
||||
reinterpret_cast<const StackFrameX86*>(frame);
|
||||
|
||||
if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EIP)
|
||||
sequence = PrintRegister("eip", frame_x86->context.eip, sequence);
|
||||
if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP)
|
||||
sequence = PrintRegister("esp", frame_x86->context.esp, sequence);
|
||||
if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBP)
|
||||
sequence = PrintRegister("ebp", frame_x86->context.ebp, sequence);
|
||||
if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBX)
|
||||
sequence = PrintRegister("ebx", frame_x86->context.ebx, sequence);
|
||||
if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESI)
|
||||
sequence = PrintRegister("esi", frame_x86->context.esi, sequence);
|
||||
if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EDI)
|
||||
sequence = PrintRegister("edi", frame_x86->context.edi, sequence);
|
||||
if (frame_x86->context_validity == StackFrameX86::CONTEXT_VALID_ALL) {
|
||||
sequence = PrintRegister("eax", frame_x86->context.eax, sequence);
|
||||
sequence = PrintRegister("ecx", frame_x86->context.ecx, sequence);
|
||||
sequence = PrintRegister("edx", frame_x86->context.edx, sequence);
|
||||
sequence = PrintRegister("efl", frame_x86->context.eflags, sequence);
|
||||
}
|
||||
} else if (cpu == "ppc") {
|
||||
const StackFramePPC *frame_ppc =
|
||||
reinterpret_cast<const StackFramePPC*>(frame);
|
||||
|
||||
if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_ALL ==
|
||||
StackFramePPC::CONTEXT_VALID_ALL) {
|
||||
sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence);
|
||||
sequence = PrintRegister("srr1", frame_ppc->context.srr1, sequence);
|
||||
sequence = PrintRegister("cr", frame_ppc->context.cr, sequence);
|
||||
sequence = PrintRegister("xer", frame_ppc->context.xer, sequence);
|
||||
sequence = PrintRegister("lr", frame_ppc->context.lr, sequence);
|
||||
sequence = PrintRegister("ctr", frame_ppc->context.ctr, sequence);
|
||||
sequence = PrintRegister("mq", frame_ppc->context.mq, sequence);
|
||||
sequence = PrintRegister("vrsave", frame_ppc->context.vrsave, sequence);
|
||||
|
||||
sequence = 0;
|
||||
char buffer[5];
|
||||
for (int i = 0; i < MD_CONTEXT_PPC_GPR_COUNT; ++i) {
|
||||
sprintf(buffer, "r%d", i);
|
||||
sequence = PrintRegister(buffer, frame_ppc->context.gpr[i], sequence);
|
||||
}
|
||||
} else {
|
||||
if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_SRR0)
|
||||
sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence);
|
||||
if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_GPR1)
|
||||
sequence = PrintRegister("r1", frame_ppc->context.gpr[1], sequence);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
static void Start(Options *options) {
|
||||
string minidump_file([options->minidumpPath fileSystemRepresentation]);
|
||||
|
||||
// Guess that the symbols are for our default architecture
|
||||
const NXArchInfo *localArchInfo = NXGetLocalArchInfo();
|
||||
string arch = "ppc";
|
||||
|
||||
if (!localArchInfo)
|
||||
return;
|
||||
|
||||
if (localArchInfo->cputype & CPU_ARCH_ABI64)
|
||||
arch = ((localArchInfo->cputype & ~CPU_ARCH_ABI64) == CPU_TYPE_X86) ?
|
||||
"x86_64" : "ppc64";
|
||||
else
|
||||
arch = (localArchInfo->cputype == CPU_TYPE_X86) ? "x86" : "ppc";
|
||||
|
||||
BasicSourceLineResolver resolver;
|
||||
string search_dir = options->searchDir ?
|
||||
[options->searchDir fileSystemRepresentation] : "";
|
||||
scoped_ptr<OnDemandSymbolSupplier> symbol_supplier(
|
||||
new OnDemandSymbolSupplier(arch, search_dir));
|
||||
scoped_ptr<MinidumpProcessor>
|
||||
minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver));
|
||||
ProcessState process_state;
|
||||
if (minidump_processor->Process(minidump_file, &process_state) !=
|
||||
MinidumpProcessor::PROCESS_OK) {
|
||||
fprintf(stderr, "MinidumpProcessor::Process failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
string cpu = process_state.cpu();
|
||||
// If the minidump is different than the default architecture
|
||||
if (cpu != arch) {
|
||||
symbol_supplier.reset(new OnDemandSymbolSupplier(cpu, search_dir));
|
||||
minidump_processor.reset(new MinidumpProcessor(symbol_supplier.get(),
|
||||
&resolver));
|
||||
|
||||
if (minidump_processor->Process(minidump_file, &process_state) !=
|
||||
MinidumpProcessor::PROCESS_OK) {
|
||||
fprintf(stderr, "MinidumpProcessor::Process failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the time to a string
|
||||
u_int32_t time_date_stamp = process_state.time_date_stamp();
|
||||
struct tm timestruct;
|
||||
gmtime_r(reinterpret_cast<time_t*>(&time_date_stamp), ×truct);
|
||||
char timestr[20];
|
||||
strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct);
|
||||
printf("Date: %s GMT\n", timestr);
|
||||
|
||||
string cpu_info = process_state.cpu_info();
|
||||
printf("Operating system: %s (%s)\n", process_state.os().c_str(),
|
||||
process_state.os_version().c_str());
|
||||
printf("Architecture: %s\n", cpu.c_str());
|
||||
|
||||
if (process_state.crashed()) {
|
||||
printf("Crash reason: %s\n", process_state.crash_reason().c_str());
|
||||
printf("Crash address: 0x%llx\n", process_state.crash_address());
|
||||
} else {
|
||||
printf("No crash\n");
|
||||
}
|
||||
|
||||
int requesting_thread = process_state.requesting_thread();
|
||||
if (requesting_thread != -1) {
|
||||
printf("\n");
|
||||
printf("Thread %d (%s)\n",
|
||||
requesting_thread,
|
||||
process_state.crashed() ? "crashed" :
|
||||
"requested dump, did not crash");
|
||||
PrintStack(process_state.threads()->at(requesting_thread), cpu);
|
||||
}
|
||||
|
||||
// Print all of the threads in the dump.
|
||||
int thread_count = process_state.threads()->size();
|
||||
for (int thread_index = 0; thread_index < thread_count; ++thread_index) {
|
||||
if (thread_index != requesting_thread) {
|
||||
// Don't print the crash thread again, it was already printed.
|
||||
printf("\n");
|
||||
printf("Thread %d\n", thread_index);
|
||||
PrintStack(process_state.threads()->at(thread_index), cpu);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the crashed registers
|
||||
if (requesting_thread != -1) {
|
||||
printf("\nThread %d:", requesting_thread);
|
||||
PrintRegisters(process_state.threads()->at(requesting_thread), cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
static void Usage(int argc, const char *argv[]) {
|
||||
fprintf(stderr, "Convert a minidump to a crash report. Airbag symbol files\n");
|
||||
fprintf(stderr, "will be used (or created if missing) in /tmp.\n");
|
||||
fprintf(stderr, "Usage: %s [-s search-dir] minidump-file\n", argv[0]);
|
||||
fprintf(stderr, "\t-s: Specify a search directory to use for missing modules\n");
|
||||
fprintf(stderr, "\t-h: Usage\n");
|
||||
fprintf(stderr, "\t-?: Usage\n");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
static void SetupOptions(int argc, const char *argv[], Options *options) {
|
||||
extern int optind;
|
||||
char ch;
|
||||
|
||||
while ((ch = getopt(argc, (char * const *)argv, "s:h?")) != -1) {
|
||||
switch (ch) {
|
||||
case 's':
|
||||
options->searchDir = [[NSFileManager defaultManager]
|
||||
stringWithFileSystemRepresentation:optarg
|
||||
length:strlen(optarg)];
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
Usage(argc, argv);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc - optind) != 1) {
|
||||
fprintf(stderr, "%s: Missing minidump file\n", argv[0]);
|
||||
Usage(argc, argv);
|
||||
}
|
||||
|
||||
options->minidumpPath = [[NSFileManager defaultManager]
|
||||
stringWithFileSystemRepresentation:argv[optind]
|
||||
length:strlen(argv[optind])];
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
int main (int argc, const char * argv[]) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
Options options;
|
||||
|
||||
bzero(&options, sizeof(Options));
|
||||
SetupOptions(argc, argv, &options);
|
||||
Start(&options);
|
||||
[pool release];
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,358 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
8DD76F9A0486AA7600D96B5E /* crash_report.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* crash_report.mm */; settings = {ATTRIBUTES = (); }; };
|
||||
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
|
||||
9B35FEE40B2675F9008DE8C7 /* code_module.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B35FEE20B2675F9008DE8C7 /* code_module.h */; };
|
||||
9B35FEE50B2675F9008DE8C7 /* code_modules.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B35FEE30B2675F9008DE8C7 /* code_modules.h */; };
|
||||
9B35FEE90B26761C008DE8C7 /* basic_code_module.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B35FEE60B26761C008DE8C7 /* basic_code_module.h */; };
|
||||
9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */; };
|
||||
9B35FEEB0B26761C008DE8C7 /* basic_code_modules.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */; };
|
||||
9B3904960B2E52D90059FABE /* basic_source_line_resolver.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */; };
|
||||
9B3904970B2E52D90059FABE /* source_line_resolver_interface.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */; };
|
||||
9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */; };
|
||||
9BDF172C0B1B8B2400F8391B /* call_stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF172A0B1B8B2400F8391B /* call_stack.cc */; };
|
||||
9BDF172D0B1B8B2400F8391B /* minidump_processor.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */; };
|
||||
9BDF17410B1B8B9A00F8391B /* minidump.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF173F0B1B8B9A00F8391B /* minidump.cc */; };
|
||||
9BDF17540B1B8BF900F8391B /* stackwalker_ppc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */; };
|
||||
9BDF17550B1B8BF900F8391B /* stackwalker_x86.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */; };
|
||||
9BDF17560B1B8BF900F8391B /* stackwalker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17530B1B8BF900F8391B /* stackwalker.cc */; };
|
||||
9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF175B0B1B8C1B00F8391B /* process_state.cc */; };
|
||||
9BDF176D0B1B8CB100F8391B /* on_demand_symbol_supplier.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */; };
|
||||
9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */; };
|
||||
9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */; };
|
||||
9BDF1AB90B1BE70C00F8391B /* range_map.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF1A7B0B1BE30100F8391B /* range_map.h */; };
|
||||
9BDF1ABA0B1BE70D00F8391B /* range_map-inl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */; };
|
||||
9BDF1AFC0B1BEB6300F8391B /* address_map-inl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */; };
|
||||
9BDF1AFD0B1BEB6300F8391B /* address_map.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF1AFB0B1BEB6300F8391B /* address_map.h */; };
|
||||
9BDF21A60B1E825400F8391B /* dump_syms.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BDF192D0B1BC15D00F8391B /* dump_syms.h */; };
|
||||
9BDF21A70B1E825400F8391B /* dump_syms.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF192E0B1BC15D00F8391B /* dump_syms.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
8DD76F9E0486AA7600D96B5E /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
9BDF176D0B1B8CB100F8391B /* on_demand_symbol_supplier.h in CopyFiles */,
|
||||
9BDF1AB90B1BE70C00F8391B /* range_map.h in CopyFiles */,
|
||||
9BDF1ABA0B1BE70D00F8391B /* range_map-inl.h in CopyFiles */,
|
||||
9BDF1AFC0B1BEB6300F8391B /* address_map-inl.h in CopyFiles */,
|
||||
9BDF1AFD0B1BEB6300F8391B /* address_map.h in CopyFiles */,
|
||||
9BDF21A60B1E825400F8391B /* dump_syms.h in CopyFiles */,
|
||||
9B35FEE40B2675F9008DE8C7 /* code_module.h in CopyFiles */,
|
||||
9B35FEE50B2675F9008DE8C7 /* code_modules.h in CopyFiles */,
|
||||
9B35FEE90B26761C008DE8C7 /* basic_code_module.h in CopyFiles */,
|
||||
9B35FEEB0B26761C008DE8C7 /* basic_code_modules.h in CopyFiles */,
|
||||
9B3904960B2E52D90059FABE /* basic_source_line_resolver.h in CopyFiles */,
|
||||
9B3904970B2E52D90059FABE /* source_line_resolver_interface.h in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
08FB7796FE84155DC02AAC07 /* crash_report.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = crash_report.mm; sourceTree = "<group>"; };
|
||||
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
8DD76FA10486AA7600D96B5E /* crash_report */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = crash_report; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9B35FEE20B2675F9008DE8C7 /* code_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = code_module.h; path = ../../../google_airbag/processor/code_module.h; sourceTree = SOURCE_ROOT; };
|
||||
9B35FEE30B2675F9008DE8C7 /* code_modules.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = code_modules.h; path = ../../../google_airbag/processor/code_modules.h; sourceTree = SOURCE_ROOT; };
|
||||
9B35FEE60B26761C008DE8C7 /* basic_code_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = basic_code_module.h; path = ../../../processor/basic_code_module.h; sourceTree = SOURCE_ROOT; };
|
||||
9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = basic_code_modules.cc; path = ../../../processor/basic_code_modules.cc; sourceTree = SOURCE_ROOT; };
|
||||
9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = basic_code_modules.h; path = ../../../processor/basic_code_modules.h; sourceTree = SOURCE_ROOT; };
|
||||
9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = basic_source_line_resolver.h; sourceTree = "<group>"; };
|
||||
9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source_line_resolver_interface.h; sourceTree = "<group>"; };
|
||||
9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = basic_source_line_resolver.cc; path = ../../../processor/basic_source_line_resolver.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF16F90B1B8ACD00F8391B /* airbag_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = airbag_types.h; sourceTree = "<group>"; };
|
||||
9BDF16FA0B1B8ACD00F8391B /* minidump_format.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_format.h; sourceTree = "<group>"; };
|
||||
9BDF16FC0B1B8ACD00F8391B /* call_stack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = call_stack.h; sourceTree = "<group>"; };
|
||||
9BDF16FD0B1B8ACD00F8391B /* memory_region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = memory_region.h; sourceTree = "<group>"; };
|
||||
9BDF16FE0B1B8ACD00F8391B /* minidump.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump.h; sourceTree = "<group>"; };
|
||||
9BDF16FF0B1B8ACD00F8391B /* minidump_processor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_processor.h; sourceTree = "<group>"; };
|
||||
9BDF17000B1B8ACD00F8391B /* process_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = process_state.h; sourceTree = "<group>"; };
|
||||
9BDF17010B1B8ACD00F8391B /* stack_frame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stack_frame.h; sourceTree = "<group>"; };
|
||||
9BDF17020B1B8ACD00F8391B /* stack_frame_cpu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stack_frame_cpu.h; sourceTree = "<group>"; };
|
||||
9BDF17030B1B8ACD00F8391B /* stackwalker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stackwalker.h; sourceTree = "<group>"; };
|
||||
9BDF17040B1B8ACD00F8391B /* symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = symbol_supplier.h; sourceTree = "<group>"; };
|
||||
9BDF172A0B1B8B2400F8391B /* call_stack.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = call_stack.cc; path = ../../../processor/call_stack.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_processor.cc; path = ../../../processor/minidump_processor.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF173F0B1B8B9A00F8391B /* minidump.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump.cc; path = ../../../processor/minidump.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_ppc.cc; path = ../../../processor/stackwalker_ppc.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_x86.cc; path = ../../../processor/stackwalker_x86.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF17530B1B8BF900F8391B /* stackwalker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker.cc; path = ../../../processor/stackwalker.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF175B0B1B8C1B00F8391B /* process_state.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = process_state.cc; path = ../../../processor/process_state.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = on_demand_symbol_supplier.h; sourceTree = "<group>"; };
|
||||
9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = on_demand_symbol_supplier.mm; sourceTree = "<group>"; };
|
||||
9BDF192D0B1BC15D00F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = SOURCE_ROOT; };
|
||||
9BDF192E0B1BC15D00F8391B /* dump_syms.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = dump_syms.m; path = ../../../common/mac/dump_syms.m; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pathname_stripper.cc; path = ../../../processor/pathname_stripper.cc; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "range_map-inl.h"; path = "../../../processor/range_map-inl.h"; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1A7B0B1BE30100F8391B /* range_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = range_map.h; path = ../../../processor/range_map.h; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "address_map-inl.h"; path = "../../../processor/address_map-inl.h"; sourceTree = SOURCE_ROOT; };
|
||||
9BDF1AFB0B1BEB6300F8391B /* address_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = address_map.h; path = ../../../processor/address_map.h; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8DD76F9B0486AA7600D96B5E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
08FB7794FE84155DC02AAC07 /* crash_report */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BDF192D0B1BC15D00F8391B /* dump_syms.h */,
|
||||
9BDF192E0B1BC15D00F8391B /* dump_syms.m */,
|
||||
08FB7796FE84155DC02AAC07 /* crash_report.mm */,
|
||||
9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */,
|
||||
9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */,
|
||||
08FB7795FE84155DC02AAC07 /* airbag */,
|
||||
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
);
|
||||
name = crash_report;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7795FE84155DC02AAC07 /* airbag */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BDF17280B1B8B0200F8391B /* processor */,
|
||||
9BDF16F70B1B8ACD00F8391B /* google_airbag */,
|
||||
);
|
||||
name = airbag;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
08FB779EFE84155DC02AAC07 /* Foundation.framework */,
|
||||
);
|
||||
name = "External Frameworks and Libraries";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8DD76FA10486AA7600D96B5E /* crash_report */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9BDF16F70B1B8ACD00F8391B /* google_airbag */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BDF16F80B1B8ACD00F8391B /* common */,
|
||||
9BDF16FB0B1B8ACD00F8391B /* processor */,
|
||||
);
|
||||
name = google_airbag;
|
||||
path = ../../../google_airbag;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
9BDF16F80B1B8ACD00F8391B /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9BDF16F90B1B8ACD00F8391B /* airbag_types.h */,
|
||||
9BDF16FA0B1B8ACD00F8391B /* minidump_format.h */,
|
||||
);
|
||||
path = common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9BDF16FB0B1B8ACD00F8391B /* processor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */,
|
||||
9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */,
|
||||
9BDF16FC0B1B8ACD00F8391B /* call_stack.h */,
|
||||
9B35FEE20B2675F9008DE8C7 /* code_module.h */,
|
||||
9B35FEE30B2675F9008DE8C7 /* code_modules.h */,
|
||||
9BDF16FD0B1B8ACD00F8391B /* memory_region.h */,
|
||||
9BDF16FE0B1B8ACD00F8391B /* minidump.h */,
|
||||
9BDF16FF0B1B8ACD00F8391B /* minidump_processor.h */,
|
||||
9BDF17000B1B8ACD00F8391B /* process_state.h */,
|
||||
9BDF17010B1B8ACD00F8391B /* stack_frame.h */,
|
||||
9BDF17020B1B8ACD00F8391B /* stack_frame_cpu.h */,
|
||||
9BDF17030B1B8ACD00F8391B /* stackwalker.h */,
|
||||
9BDF17040B1B8ACD00F8391B /* symbol_supplier.h */,
|
||||
);
|
||||
path = processor;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9BDF17280B1B8B0200F8391B /* processor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */,
|
||||
9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */,
|
||||
9BDF1AFB0B1BEB6300F8391B /* address_map.h */,
|
||||
9B35FEE60B26761C008DE8C7 /* basic_code_module.h */,
|
||||
9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */,
|
||||
9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */,
|
||||
9BDF172A0B1B8B2400F8391B /* call_stack.cc */,
|
||||
9BDF173F0B1B8B9A00F8391B /* minidump.cc */,
|
||||
9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */,
|
||||
9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */,
|
||||
9BDF175B0B1B8C1B00F8391B /* process_state.cc */,
|
||||
9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */,
|
||||
9BDF1A7B0B1BE30100F8391B /* range_map.h */,
|
||||
9BDF17530B1B8BF900F8391B /* stackwalker.cc */,
|
||||
9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */,
|
||||
9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */,
|
||||
);
|
||||
name = processor;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8DD76F960486AA7600D96B5E /* crash_report */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "crash_report" */;
|
||||
buildPhases = (
|
||||
8DD76F990486AA7600D96B5E /* Sources */,
|
||||
8DD76F9B0486AA7600D96B5E /* Frameworks */,
|
||||
8DD76F9E0486AA7600D96B5E /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = crash_report;
|
||||
productInstallPath = "$(HOME)/bin";
|
||||
productName = crash_report;
|
||||
productReference = 8DD76FA10486AA7600D96B5E /* crash_report */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "crash_report" */;
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* crash_report */;
|
||||
projectDirPath = "";
|
||||
targets = (
|
||||
8DD76F960486AA7600D96B5E /* crash_report */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8DD76F990486AA7600D96B5E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8DD76F9A0486AA7600D96B5E /* crash_report.mm in Sources */,
|
||||
9BDF172C0B1B8B2400F8391B /* call_stack.cc in Sources */,
|
||||
9BDF172D0B1B8B2400F8391B /* minidump_processor.cc in Sources */,
|
||||
9BDF17410B1B8B9A00F8391B /* minidump.cc in Sources */,
|
||||
9BDF17540B1B8BF900F8391B /* stackwalker_ppc.cc in Sources */,
|
||||
9BDF17550B1B8BF900F8391B /* stackwalker_x86.cc in Sources */,
|
||||
9BDF17560B1B8BF900F8391B /* stackwalker.cc in Sources */,
|
||||
9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */,
|
||||
9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */,
|
||||
9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */,
|
||||
9BDF21A70B1E825400F8391B /* dump_syms.m in Sources */,
|
||||
9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */,
|
||||
9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DEB927508733DD40010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
PRODUCT_NAME = crash_report;
|
||||
USER_HEADER_SEARCH_PATHS = "../../../../** $(inherited)";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB927608733DD40010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
PRODUCT_NAME = crash_report;
|
||||
USER_HEADER_SEARCH_PATHS = "../../../../** $(inherited)";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1DEB927908733DD40010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB927A08733DD40010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "crash_report" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB927508733DD40010E9CD /* Debug */,
|
||||
1DEB927608733DD40010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "crash_report" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB927908733DD40010E9CD /* Debug */,
|
||||
1DEB927A08733DD40010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
}
|
92
src/tools/mac/crash_report/on_demand_symbol_supplier.h
Normal file
92
src/tools/mac/crash_report/on_demand_symbol_supplier.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
// 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.
|
||||
|
||||
// on_demand_symbol_supplier.h: Provides a Symbol Supplier that will create
|
||||
// an airbag symbol file on demand.
|
||||
|
||||
#ifndef TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
|
||||
#define TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "google_airbag/processor/symbol_supplier.h"
|
||||
|
||||
namespace google_airbag {
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
class MinidumpModule;
|
||||
|
||||
class OnDemandSymbolSupplier : public SymbolSupplier {
|
||||
public:
|
||||
// |architecture| should be one of ppc, i386, x86, ppc64, x86_64
|
||||
// |search_dir| is the directory to search for alternative symbols with
|
||||
// the same name as the module in the minidump
|
||||
OnDemandSymbolSupplier(const string &architecture, const string &search_dir);
|
||||
virtual ~OnDemandSymbolSupplier() {}
|
||||
|
||||
// Returns the path to the symbol file for the given module.
|
||||
virtual SymbolResult GetSymbolFile(const CodeModule *module,
|
||||
string *symbol_file);
|
||||
|
||||
protected:
|
||||
// Return symbols for this architecture
|
||||
string architecture_;
|
||||
|
||||
// Search directory
|
||||
string search_dir_;
|
||||
|
||||
// When we create a symbol file for a module, save the name of the module
|
||||
// and the path to that module's symbol file.
|
||||
map<string, string> module_file_map_;
|
||||
|
||||
// Return the name for |module| This will be the value used as the key
|
||||
// to the |module_file_map_|.
|
||||
string GetNameForModule(const CodeModule *module);
|
||||
|
||||
// Find the module on local system. If the module resides in a different
|
||||
// location than the full path in the minidump, this will be the location
|
||||
// used.
|
||||
string GetLocalModulePath(const CodeModule *module);
|
||||
|
||||
// Return the full path for |module|.
|
||||
string GetModulePath(const CodeModule *module);
|
||||
|
||||
// Return the path to the symbol file for |module|. If an empty string is
|
||||
// returned, then |module| doesn't have a symbol file.
|
||||
string GetModuleSymbolFile(const CodeModule *module);
|
||||
|
||||
// Generate the airbag symbol file for |module|. Return true if successful.
|
||||
// File is generated in /tmp.
|
||||
bool GenerateSymbolFile(const CodeModule *module);
|
||||
};
|
||||
|
||||
} // namespace google_airbag
|
||||
|
||||
#endif // TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__
|
178
src/tools/mac/crash_report/on_demand_symbol_supplier.mm
Normal file
178
src/tools/mac/crash_report/on_demand_symbol_supplier.mm
Normal file
|
@ -0,0 +1,178 @@
|
|||
// 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.
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "google_airbag/processor/basic_source_line_resolver.h"
|
||||
#include "google_airbag/processor/minidump.h"
|
||||
#include "processor/pathname_stripper.h"
|
||||
|
||||
#include "on_demand_symbol_supplier.h"
|
||||
#include "dump_syms.h"
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
using google_airbag::OnDemandSymbolSupplier;
|
||||
using google_airbag::PathnameStripper;
|
||||
using google_airbag::SymbolSupplier;
|
||||
|
||||
OnDemandSymbolSupplier::OnDemandSymbolSupplier(const string &architecture,
|
||||
const string &search_dir)
|
||||
: architecture_(architecture),
|
||||
search_dir_(search_dir) {
|
||||
}
|
||||
|
||||
SymbolSupplier::SymbolResult
|
||||
OnDemandSymbolSupplier::GetSymbolFile(const CodeModule *module,
|
||||
string *symbol_file) {
|
||||
string path(GetModuleSymbolFile(module));
|
||||
|
||||
if (path.empty()) {
|
||||
if (!GenerateSymbolFile(module))
|
||||
return NOT_FOUND;
|
||||
|
||||
path = GetModuleSymbolFile(module);
|
||||
}
|
||||
|
||||
if (path.empty())
|
||||
return NOT_FOUND;
|
||||
|
||||
*symbol_file = path;
|
||||
return FOUND;
|
||||
}
|
||||
|
||||
string OnDemandSymbolSupplier::GetLocalModulePath(const CodeModule *module) {
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
const char *moduleStr = module->code_file().c_str();
|
||||
NSString *modulePath =
|
||||
[mgr stringWithFileSystemRepresentation:moduleStr length:strlen(moduleStr)];
|
||||
const char *searchStr = search_dir_.c_str();
|
||||
NSString *searchDir =
|
||||
[mgr stringWithFileSystemRepresentation:searchStr length:strlen(searchStr)];
|
||||
|
||||
if ([mgr fileExistsAtPath:modulePath])
|
||||
return module->code_file();
|
||||
|
||||
// If the module is not found, try to start appending the components to the
|
||||
// search string and stop if a file (not dir) is found or all components
|
||||
// have been appended
|
||||
NSArray *pathComponents = [modulePath componentsSeparatedByString:@"/"];
|
||||
int count = [pathComponents count];
|
||||
NSMutableString *path = [NSMutableString string];
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
[path setString:searchDir];
|
||||
|
||||
for (int j = 0; j < i + 1; ++j) {
|
||||
int idx = count - 1 - i + j;
|
||||
[path appendFormat:@"/%@", [pathComponents objectAtIndex:idx]];
|
||||
}
|
||||
|
||||
BOOL isDir;
|
||||
if ([mgr fileExistsAtPath:path isDirectory:&isDir] && (!isDir)) {
|
||||
return [path fileSystemRepresentation];
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
string OnDemandSymbolSupplier::GetModulePath(const CodeModule *module) {
|
||||
return module->code_file();
|
||||
}
|
||||
|
||||
string OnDemandSymbolSupplier::GetNameForModule(const CodeModule *module) {
|
||||
return PathnameStripper::File(module->code_file());
|
||||
}
|
||||
|
||||
string OnDemandSymbolSupplier::GetModuleSymbolFile(const CodeModule *module) {
|
||||
string name(GetNameForModule(module));
|
||||
map<string, string>::iterator result = module_file_map_.find(name);
|
||||
|
||||
return (result == module_file_map_.end()) ? "" : (*result).second;
|
||||
}
|
||||
|
||||
static float GetFileModificationTime(const char *path) {
|
||||
float result = 0;
|
||||
struct stat file_stat;
|
||||
if (stat(path, &file_stat) == 0)
|
||||
result = (float)file_stat.st_mtimespec.tv_sec +
|
||||
(float)file_stat.st_mtimespec.tv_nsec / 1.0e9;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OnDemandSymbolSupplier::GenerateSymbolFile(const CodeModule *module) {
|
||||
bool result = true;
|
||||
string name = GetNameForModule(module);
|
||||
string module_path = GetLocalModulePath(module);
|
||||
NSString *symbol_path = [NSString stringWithFormat:@"/tmp/%s.%s.sym",
|
||||
name.c_str(), architecture_.c_str()];
|
||||
|
||||
if (module_path.empty())
|
||||
return false;
|
||||
|
||||
// Check if there's already a symbol file cached. Ensure that the file is
|
||||
// newer than the module. Otherwise, generate a new one.
|
||||
BOOL generate_file = YES;
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:symbol_path]) {
|
||||
// Check if the module file is newer than the saved symbols
|
||||
float cache_time =
|
||||
GetFileModificationTime([symbol_path fileSystemRepresentation]);
|
||||
float module_time =
|
||||
GetFileModificationTime(module_path.c_str());
|
||||
|
||||
if (cache_time > module_time)
|
||||
generate_file = NO;
|
||||
}
|
||||
|
||||
if (generate_file) {
|
||||
NSString *module_str = [[NSFileManager defaultManager]
|
||||
stringWithFileSystemRepresentation:module_path.c_str()
|
||||
length:module_path.length()];
|
||||
DumpSymbols *dump = [[DumpSymbols alloc] initWithContentsOfFile:module_str];
|
||||
const char *archStr = architecture_.c_str();
|
||||
if ([dump setArchitecture:[NSString stringWithUTF8String:archStr]]) {
|
||||
[dump writeSymbolFile:symbol_path];
|
||||
} else {
|
||||
printf("Architecture %s not available for %s\n", archStr, name.c_str());
|
||||
result = false;
|
||||
}
|
||||
[dump release];
|
||||
}
|
||||
|
||||
// Add the mapping
|
||||
if (result)
|
||||
module_file_map_[name] = [symbol_path fileSystemRepresentation];
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Reference in a new issue