1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-12 09:04:33 +02:00

Update breakpad to make it work with MinGW

This commit is contained in:
Dominik Schmidt
2014-04-14 19:23:44 +02:00
parent c912b76c49
commit b4f05b0831
1049 changed files with 57520 additions and 329083 deletions

View File

@@ -39,6 +39,8 @@
#include <string>
#include <vector>
#include "common/scoped_ptr.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/basic_source_line_resolver.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/code_module.h"
@@ -49,12 +51,10 @@
#include "google_breakpad/processor/stack_frame_cpu.h"
#include "processor/logging.h"
#include "processor/pathname_stripper.h"
#include "processor/scoped_ptr.h"
#include "processor/simple_symbol_supplier.h"
namespace {
using std::string;
using std::vector;
using google_breakpad::BasicSourceLineResolver;
using google_breakpad::CallStack;
@@ -72,6 +72,8 @@ using google_breakpad::StackFrameSPARC;
using google_breakpad::StackFrameX86;
using google_breakpad::StackFrameAMD64;
using google_breakpad::StackFrameARM;
using google_breakpad::StackFrameARM64;
using google_breakpad::StackFrameMIPS;
// Separator character for machine readable output.
static const char kOutputSeparator = '|';
@@ -84,11 +86,11 @@ static const char kOutputSeparator = '|';
// of registers is completely printed, regardless of the number of calls
// to PrintRegister.
static const int kMaxWidth = 80; // optimize for an 80-column terminal
static int PrintRegister(const char *name, u_int32_t value, int start_col) {
static int PrintRegister(const char *name, uint32_t value, int start_col) {
char buffer[64];
snprintf(buffer, sizeof(buffer), " %5s = 0x%08x", name, value);
if (start_col + strlen(buffer) > kMaxWidth) {
if (start_col + static_cast<ssize_t>(strlen(buffer)) > kMaxWidth) {
start_col = 0;
printf("\n ");
}
@@ -98,11 +100,11 @@ static int PrintRegister(const char *name, u_int32_t value, int start_col) {
}
// PrintRegister64 does the same thing, but for 64-bit registers.
static int PrintRegister64(const char *name, u_int64_t value, int start_col) {
static int PrintRegister64(const char *name, uint64_t value, int start_col) {
char buffer[64];
snprintf(buffer, sizeof(buffer), " %5s = 0x%016" PRIx64 , name, value);
if (start_col + strlen(buffer) > kMaxWidth) {
if (start_col + static_cast<ssize_t>(strlen(buffer)) > kMaxWidth) {
start_col = 0;
printf("\n ");
}
@@ -137,10 +139,15 @@ static string StripSeparator(const string &original) {
// frame printed is also output, if available.
static void PrintStack(const CallStack *stack, const string &cpu) {
int frame_count = stack->frames()->size();
if (frame_count == 0) {
printf(" <no frames>\n");
}
for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
const StackFrame *frame = stack->frames()->at(frame_index);
printf("%2d ", frame_index);
uint64_t instruction_address = frame->ReturnAddress();
if (frame->module) {
printf("%s", PathnameStripper::File(frame->module->code_file()).c_str());
if (!frame->function_name.empty()) {
@@ -150,16 +157,16 @@ static void PrintStack(const CallStack *stack, const string &cpu) {
printf(" [%s : %d + 0x%" PRIx64 "]",
source_file.c_str(),
frame->source_line,
frame->instruction - frame->source_line_base);
instruction_address - frame->source_line_base);
} else {
printf(" + 0x%" PRIx64, frame->instruction - frame->function_base);
printf(" + 0x%" PRIx64, instruction_address - frame->function_base);
}
} else {
printf(" + 0x%" PRIx64,
frame->instruction - frame->module->base_address());
instruction_address - frame->module->base_address());
}
} else {
printf("0x%" PRIx64, frame->instruction);
printf("0x%" PRIx64, instruction_address);
}
printf("\n ");
@@ -228,6 +235,17 @@ static void PrintStack(const CallStack *stack, const string &cpu) {
const StackFrameARM *frame_arm =
reinterpret_cast<const StackFrameARM*>(frame);
// Argument registers (caller-saves), which will likely only be valid
// for the youngest frame.
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R0)
sequence = PrintRegister("r0", frame_arm->context.iregs[0], sequence);
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R1)
sequence = PrintRegister("r1", frame_arm->context.iregs[1], sequence);
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R2)
sequence = PrintRegister("r2", frame_arm->context.iregs[2], sequence);
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R3)
sequence = PrintRegister("r3", frame_arm->context.iregs[3], sequence);
// General-purpose callee-saves registers.
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R4)
sequence = PrintRegister("r4", frame_arm->context.iregs[4], sequence);
@@ -243,6 +261,8 @@ static void PrintStack(const CallStack *stack, const string &cpu) {
sequence = PrintRegister("r9", frame_arm->context.iregs[9], sequence);
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R10)
sequence = PrintRegister("r10", frame_arm->context.iregs[10], sequence);
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R12)
sequence = PrintRegister("r12", frame_arm->context.iregs[12], sequence);
// Registers with a dedicated or conventional purpose.
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_FP)
@@ -253,6 +273,200 @@ static void PrintStack(const CallStack *stack, const string &cpu) {
sequence = PrintRegister("lr", frame_arm->context.iregs[14], sequence);
if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_PC)
sequence = PrintRegister("pc", frame_arm->context.iregs[15], sequence);
} else if (cpu == "arm64") {
const StackFrameARM64 *frame_arm64 =
reinterpret_cast<const StackFrameARM64*>(frame);
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X0) {
sequence =
PrintRegister64("x0", frame_arm64->context.iregs[0], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X1) {
sequence =
PrintRegister64("x1", frame_arm64->context.iregs[1], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X2) {
sequence =
PrintRegister64("x2", frame_arm64->context.iregs[2], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X3) {
sequence =
PrintRegister64("x3", frame_arm64->context.iregs[3], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X4) {
sequence =
PrintRegister64("x4", frame_arm64->context.iregs[4], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X5) {
sequence =
PrintRegister64("x5", frame_arm64->context.iregs[5], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X6) {
sequence =
PrintRegister64("x6", frame_arm64->context.iregs[6], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X7) {
sequence =
PrintRegister64("x7", frame_arm64->context.iregs[7], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X8) {
sequence =
PrintRegister64("x8", frame_arm64->context.iregs[8], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X9) {
sequence =
PrintRegister64("x9", frame_arm64->context.iregs[9], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X10) {
sequence =
PrintRegister64("x10", frame_arm64->context.iregs[10], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X11) {
sequence =
PrintRegister64("x11", frame_arm64->context.iregs[11], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X12) {
sequence =
PrintRegister64("x12", frame_arm64->context.iregs[12], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X13) {
sequence =
PrintRegister64("x13", frame_arm64->context.iregs[13], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X14) {
sequence =
PrintRegister64("x14", frame_arm64->context.iregs[14], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X15) {
sequence =
PrintRegister64("x15", frame_arm64->context.iregs[15], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X16) {
sequence =
PrintRegister64("x16", frame_arm64->context.iregs[16], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X17) {
sequence =
PrintRegister64("x17", frame_arm64->context.iregs[17], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X18) {
sequence =
PrintRegister64("x18", frame_arm64->context.iregs[18], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X19) {
sequence =
PrintRegister64("x19", frame_arm64->context.iregs[19], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X20) {
sequence =
PrintRegister64("x20", frame_arm64->context.iregs[20], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X21) {
sequence =
PrintRegister64("x21", frame_arm64->context.iregs[21], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X22) {
sequence =
PrintRegister64("x22", frame_arm64->context.iregs[22], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X23) {
sequence =
PrintRegister64("x23", frame_arm64->context.iregs[23], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X24) {
sequence =
PrintRegister64("x24", frame_arm64->context.iregs[24], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X25) {
sequence =
PrintRegister64("x25", frame_arm64->context.iregs[25], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X26) {
sequence =
PrintRegister64("x26", frame_arm64->context.iregs[26], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X27) {
sequence =
PrintRegister64("x27", frame_arm64->context.iregs[27], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X28) {
sequence =
PrintRegister64("x28", frame_arm64->context.iregs[28], sequence);
}
// Registers with a dedicated or conventional purpose.
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_FP) {
sequence =
PrintRegister64("fp", frame_arm64->context.iregs[29], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_LR) {
sequence =
PrintRegister64("lr", frame_arm64->context.iregs[30], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_SP) {
sequence =
PrintRegister64("sp", frame_arm64->context.iregs[31], sequence);
}
if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_PC) {
sequence =
PrintRegister64("pc", frame_arm64->context.iregs[32], sequence);
}
} else if (cpu == "mips") {
const StackFrameMIPS* frame_mips =
reinterpret_cast<const StackFrameMIPS*>(frame);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_GP)
sequence = PrintRegister64("gp",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_GP],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_SP)
sequence = PrintRegister64("sp",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_SP],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_FP)
sequence = PrintRegister64("fp",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_FP],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_RA)
sequence = PrintRegister64("ra",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_RA],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_PC)
sequence = PrintRegister64("pc", frame_mips->context.epc, sequence);
// Save registers s0-s7
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S0)
sequence = PrintRegister64("s0",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S0],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S1)
sequence = PrintRegister64("s1",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S1],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S2)
sequence = PrintRegister64("s2",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S2],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S3)
sequence = PrintRegister64("s3",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S3],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S4)
sequence = PrintRegister64("s4",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S4],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S5)
sequence = PrintRegister64("s5",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S5],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S6)
sequence = PrintRegister64("s6",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S6],
sequence);
if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S7)
sequence = PrintRegister64("s7",
frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S7],
sequence);
}
printf("\n Found by: %s\n", frame->trust_description().c_str());
}
@@ -272,6 +486,8 @@ static void PrintStackMachineReadable(int thread_num, const CallStack *stack) {
printf("%d%c%d%c", thread_num, kOutputSeparator, frame_index,
kOutputSeparator);
uint64_t instruction_address = frame->ReturnAddress();
if (frame->module) {
assert(!frame->module->code_file().empty());
printf("%s", StripSeparator(PathnameStripper::File(
@@ -286,13 +502,13 @@ static void PrintStackMachineReadable(int thread_num, const CallStack *stack) {
kOutputSeparator,
frame->source_line,
kOutputSeparator,
frame->instruction - frame->source_line_base);
instruction_address - frame->source_line_base);
} else {
printf("%c%c%c0x%" PRIx64,
kOutputSeparator, // empty source file
kOutputSeparator, // empty source line
kOutputSeparator,
frame->instruction - frame->function_base);
instruction_address - frame->function_base);
}
} else {
printf("%c%c%c%c0x%" PRIx64,
@@ -300,7 +516,7 @@ static void PrintStackMachineReadable(int thread_num, const CallStack *stack) {
kOutputSeparator, // empty source file
kOutputSeparator, // empty source line
kOutputSeparator,
frame->instruction - frame->module->base_address());
instruction_address - frame->module->base_address());
}
} else {
// the printf before this prints a trailing separator for module name
@@ -309,20 +525,70 @@ static void PrintStackMachineReadable(int thread_num, const CallStack *stack) {
kOutputSeparator, // empty source file
kOutputSeparator, // empty source line
kOutputSeparator,
frame->instruction);
instruction_address);
}
printf("\n");
}
}
static void PrintModules(const CodeModules *modules) {
// ContainsModule checks whether a given |module| is in the vector
// |modules_without_symbols|.
static bool ContainsModule(
const vector<const CodeModule*> *modules,
const CodeModule *module) {
assert(modules);
assert(module);
vector<const CodeModule*>::const_iterator iter;
for (iter = modules->begin(); iter != modules->end(); ++iter) {
if (module->debug_file().compare((*iter)->debug_file()) == 0 &&
module->debug_identifier().compare((*iter)->debug_identifier()) == 0) {
return true;
}
}
return false;
}
// PrintModule prints a single |module| to stdout.
// |modules_without_symbols| should contain the list of modules that were
// confirmed to be missing their symbols during the stack walk.
static void PrintModule(
const CodeModule *module,
const vector<const CodeModule*> *modules_without_symbols,
const vector<const CodeModule*> *modules_with_corrupt_symbols,
uint64_t main_address) {
string symbol_issues;
if (ContainsModule(modules_without_symbols, module)) {
symbol_issues = " (WARNING: No symbols, " +
PathnameStripper::File(module->debug_file()) + ", " +
module->debug_identifier() + ")";
} else if (ContainsModule(modules_with_corrupt_symbols, module)) {
symbol_issues = " (WARNING: Corrupt symbols, " +
PathnameStripper::File(module->debug_file()) + ", " +
module->debug_identifier() + ")";
}
uint64_t base_address = module->base_address();
printf("0x%08" PRIx64 " - 0x%08" PRIx64 " %s %s%s%s\n",
base_address, base_address + module->size() - 1,
PathnameStripper::File(module->code_file()).c_str(),
module->version().empty() ? "???" : module->version().c_str(),
main_address != 0 && base_address == main_address ? " (main)" : "",
symbol_issues.c_str());
}
// PrintModules prints the list of all loaded |modules| to stdout.
// |modules_without_symbols| should contain the list of modules that were
// confirmed to be missing their symbols during the stack walk.
static void PrintModules(
const CodeModules *modules,
const vector<const CodeModule*> *modules_without_symbols,
const vector<const CodeModule*> *modules_with_corrupt_symbols) {
if (!modules)
return;
printf("\n");
printf("Loaded modules:\n");
u_int64_t main_address = 0;
uint64_t main_address = 0;
const CodeModule *main_module = modules->GetMainModule();
if (main_module) {
main_address = main_module->base_address();
@@ -333,13 +599,8 @@ static void PrintModules(const CodeModules *modules) {
module_sequence < module_count;
++module_sequence) {
const CodeModule *module = modules->GetModuleAtSequence(module_sequence);
u_int64_t base_address = module->base_address();
printf("0x%08" PRIx64 " - 0x%08" PRIx64 " %s %s%s\n",
base_address, base_address + module->size() - 1,
PathnameStripper::File(module->code_file()).c_str(),
module->version().empty() ? "???" : module->version().c_str(),
main_module != NULL && base_address == main_address ?
" (main)" : "");
PrintModule(module, modules_without_symbols, modules_with_corrupt_symbols,
main_address);
}
}
@@ -352,7 +613,7 @@ static void PrintModulesMachineReadable(const CodeModules *modules) {
if (!modules)
return;
u_int64_t main_address = 0;
uint64_t main_address = 0;
const CodeModule *main_module = modules->GetMainModule();
if (main_module) {
main_address = main_module->base_address();
@@ -363,7 +624,7 @@ static void PrintModulesMachineReadable(const CodeModules *modules) {
module_sequence < module_count;
++module_sequence) {
const CodeModule *module = modules->GetModuleAtSequence(module_sequence);
u_int64_t base_address = module->base_address();
uint64_t base_address = module->base_address();
printf("Module%c%s%c%s%c%s%c%s%c0x%08" PRIx64 "%c0x%08" PRIx64 "%c%d\n",
kOutputSeparator,
StripSeparator(PathnameStripper::File(module->code_file())).c_str(),
@@ -431,7 +692,9 @@ static void PrintProcessState(const ProcessState& process_state) {
}
}
PrintModules(process_state.modules());
PrintModules(process_state.modules(),
process_state.modules_without_symbols(),
process_state.modules_with_corrupt_symbols());
}
static void PrintProcessStateMachineReadable(const ProcessState& process_state)
@@ -575,7 +838,7 @@ int main(int argc, char **argv) {
}
// extra arguments are symbol paths
std::vector<std::string> symbol_paths;
std::vector<string> symbol_paths;
if (argc > symbol_path_arg) {
for (int argi = symbol_path_arg; argi < argc; ++argi)
symbol_paths.push_back(argv[argi]);