| Index: base/debug/stack_trace_posix.cc
|
| diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc
|
| index 8a8ae47710b1e52d3a4cf7461dd4067e36243078..0a52a52a5baf1852154fe55ddd907cfbd1183864 100644
|
| --- a/base/debug/stack_trace_posix.cc
|
| +++ b/base/debug/stack_trace_posix.cc
|
| @@ -27,6 +27,7 @@
|
|
|
| #include "base/basictypes.h"
|
| #include "base/debug/debugger.h"
|
| +#include "base/debug/format.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| @@ -112,12 +113,9 @@ class BacktraceOutputHandler {
|
| };
|
|
|
| void OutputPointer(void* pointer, BacktraceOutputHandler* handler) {
|
| - char buf[1024] = { '\0' };
|
| - handler->HandleOutput(" [0x");
|
| - internal::itoa_r(reinterpret_cast<intptr_t>(pointer),
|
| - buf, sizeof(buf), 16, 12);
|
| + char buf[30];
|
| + Format(buf, " [0x%12x]", reinterpret_cast<intptr_t>(pointer));
|
| handler->HandleOutput(buf);
|
| - handler->HandleOutput("]");
|
| }
|
|
|
| void ProcessBacktrace(void *const *trace,
|
| @@ -188,67 +186,65 @@ void StackDumpSignalHandler(int signal, siginfo_t* info, void* void_context) {
|
| if (BeingDebugged())
|
| BreakDebugger();
|
|
|
| - PrintToStderr("Received signal ");
|
| - char buf[1024] = { 0 };
|
| - internal::itoa_r(signal, buf, sizeof(buf), 10, 0);
|
| + char buf[80];
|
| + Format(buf, "Received signal %d ", signal);
|
| PrintToStderr(buf);
|
| if (signal == SIGBUS) {
|
| if (info->si_code == BUS_ADRALN)
|
| - PrintToStderr(" BUS_ADRALN ");
|
| + PrintToStderr("BUS_ADRALN ");
|
| else if (info->si_code == BUS_ADRERR)
|
| - PrintToStderr(" BUS_ADRERR ");
|
| + PrintToStderr("BUS_ADRERR ");
|
| else if (info->si_code == BUS_OBJERR)
|
| - PrintToStderr(" BUS_OBJERR ");
|
| + PrintToStderr("BUS_OBJERR ");
|
| else
|
| - PrintToStderr(" <unknown> ");
|
| + PrintToStderr("<unknown> ");
|
| } else if (signal == SIGFPE) {
|
| if (info->si_code == FPE_FLTDIV)
|
| - PrintToStderr(" FPE_FLTDIV ");
|
| + PrintToStderr("FPE_FLTDIV ");
|
| else if (info->si_code == FPE_FLTINV)
|
| - PrintToStderr(" FPE_FLTINV ");
|
| + PrintToStderr("FPE_FLTINV ");
|
| else if (info->si_code == FPE_FLTOVF)
|
| - PrintToStderr(" FPE_FLTOVF ");
|
| + PrintToStderr("FPE_FLTOVF ");
|
| else if (info->si_code == FPE_FLTRES)
|
| - PrintToStderr(" FPE_FLTRES ");
|
| + PrintToStderr("FPE_FLTRES ");
|
| else if (info->si_code == FPE_FLTSUB)
|
| - PrintToStderr(" FPE_FLTSUB ");
|
| + PrintToStderr("FPE_FLTSUB ");
|
| else if (info->si_code == FPE_FLTUND)
|
| - PrintToStderr(" FPE_FLTUND ");
|
| + PrintToStderr("FPE_FLTUND ");
|
| else if (info->si_code == FPE_INTDIV)
|
| - PrintToStderr(" FPE_INTDIV ");
|
| + PrintToStderr("FPE_INTDIV ");
|
| else if (info->si_code == FPE_INTOVF)
|
| - PrintToStderr(" FPE_INTOVF ");
|
| + PrintToStderr("FPE_INTOVF ");
|
| else
|
| - PrintToStderr(" <unknown> ");
|
| + PrintToStderr("<unknown> ");
|
| } else if (signal == SIGILL) {
|
| if (info->si_code == ILL_BADSTK)
|
| - PrintToStderr(" ILL_BADSTK ");
|
| + PrintToStderr("ILL_BADSTK ");
|
| else if (info->si_code == ILL_COPROC)
|
| - PrintToStderr(" ILL_COPROC ");
|
| + PrintToStderr("ILL_COPROC ");
|
| else if (info->si_code == ILL_ILLOPN)
|
| - PrintToStderr(" ILL_ILLOPN ");
|
| + PrintToStderr("ILL_ILLOPN ");
|
| else if (info->si_code == ILL_ILLADR)
|
| - PrintToStderr(" ILL_ILLADR ");
|
| + PrintToStderr("ILL_ILLADR ");
|
| else if (info->si_code == ILL_ILLTRP)
|
| - PrintToStderr(" ILL_ILLTRP ");
|
| + PrintToStderr("ILL_ILLTRP ");
|
| else if (info->si_code == ILL_PRVOPC)
|
| - PrintToStderr(" ILL_PRVOPC ");
|
| + PrintToStderr("ILL_PRVOPC ");
|
| else if (info->si_code == ILL_PRVREG)
|
| - PrintToStderr(" ILL_PRVREG ");
|
| + PrintToStderr("ILL_PRVREG ");
|
| else
|
| - PrintToStderr(" <unknown> ");
|
| + PrintToStderr("<unknown> ");
|
| } else if (signal == SIGSEGV) {
|
| if (info->si_code == SEGV_MAPERR)
|
| - PrintToStderr(" SEGV_MAPERR ");
|
| + PrintToStderr("SEGV_MAPERR ");
|
| else if (info->si_code == SEGV_ACCERR)
|
| - PrintToStderr(" SEGV_ACCERR ");
|
| + PrintToStderr("SEGV_ACCERR ");
|
| else
|
| - PrintToStderr(" <unknown> ");
|
| + PrintToStderr("<unknown> ");
|
| }
|
| if (signal == SIGBUS || signal == SIGFPE ||
|
| signal == SIGILL || signal == SIGSEGV) {
|
| - internal::itoa_r(reinterpret_cast<intptr_t>(info->si_addr),
|
| - buf, sizeof(buf), 16, 12);
|
| + Format(buf, "%12x", reinterpret_cast<intptr_t>(info->si_addr));
|
| PrintToStderr(buf);
|
| }
|
| PrintToStderr("\n");
|
| @@ -263,66 +259,64 @@ void StackDumpSignalHandler(int signal, siginfo_t* info, void* void_context) {
|
| greg_t value;
|
| } registers[] = {
|
| #if ARCH_CPU_32_BITS
|
| - { " gs: ", context->uc_mcontext.gregs[REG_GS] },
|
| - { " fs: ", context->uc_mcontext.gregs[REG_FS] },
|
| - { " es: ", context->uc_mcontext.gregs[REG_ES] },
|
| - { " ds: ", context->uc_mcontext.gregs[REG_DS] },
|
| - { " edi: ", context->uc_mcontext.gregs[REG_EDI] },
|
| - { " esi: ", context->uc_mcontext.gregs[REG_ESI] },
|
| - { " ebp: ", context->uc_mcontext.gregs[REG_EBP] },
|
| - { " esp: ", context->uc_mcontext.gregs[REG_ESP] },
|
| - { " ebx: ", context->uc_mcontext.gregs[REG_EBX] },
|
| - { " edx: ", context->uc_mcontext.gregs[REG_EDX] },
|
| - { " ecx: ", context->uc_mcontext.gregs[REG_ECX] },
|
| - { " eax: ", context->uc_mcontext.gregs[REG_EAX] },
|
| - { " trp: ", context->uc_mcontext.gregs[REG_TRAPNO] },
|
| - { " err: ", context->uc_mcontext.gregs[REG_ERR] },
|
| - { " ip: ", context->uc_mcontext.gregs[REG_EIP] },
|
| - { " cs: ", context->uc_mcontext.gregs[REG_CS] },
|
| - { " efl: ", context->uc_mcontext.gregs[REG_EFL] },
|
| - { " usp: ", context->uc_mcontext.gregs[REG_UESP] },
|
| - { " ss: ", context->uc_mcontext.gregs[REG_SS] },
|
| + { "gs", context->uc_mcontext.gregs[REG_GS] },
|
| + { "fs", context->uc_mcontext.gregs[REG_FS] },
|
| + { "es", context->uc_mcontext.gregs[REG_ES] },
|
| + { "ds", context->uc_mcontext.gregs[REG_DS] },
|
| + { "edi", context->uc_mcontext.gregs[REG_EDI] },
|
| + { "esi", context->uc_mcontext.gregs[REG_ESI] },
|
| + { "ebp", context->uc_mcontext.gregs[REG_EBP] },
|
| + { "esp", context->uc_mcontext.gregs[REG_ESP] },
|
| + { "ebx", context->uc_mcontext.gregs[REG_EBX] },
|
| + { "edx", context->uc_mcontext.gregs[REG_EDX] },
|
| + { "ecx", context->uc_mcontext.gregs[REG_ECX] },
|
| + { "eax", context->uc_mcontext.gregs[REG_EAX] },
|
| + { "trp", context->uc_mcontext.gregs[REG_TRAPNO] },
|
| + { "err", context->uc_mcontext.gregs[REG_ERR] },
|
| + { "ip", context->uc_mcontext.gregs[REG_EIP] },
|
| + { "cs", context->uc_mcontext.gregs[REG_CS] },
|
| + { "efl", context->uc_mcontext.gregs[REG_EFL] },
|
| + { "usp", context->uc_mcontext.gregs[REG_UESP] },
|
| + { "ss", context->uc_mcontext.gregs[REG_SS] },
|
| #elif ARCH_CPU_64_BITS
|
| - { " r8: ", context->uc_mcontext.gregs[REG_R8] },
|
| - { " r9: ", context->uc_mcontext.gregs[REG_R9] },
|
| - { " r10: ", context->uc_mcontext.gregs[REG_R10] },
|
| - { " r11: ", context->uc_mcontext.gregs[REG_R11] },
|
| - { " r12: ", context->uc_mcontext.gregs[REG_R12] },
|
| - { " r13: ", context->uc_mcontext.gregs[REG_R13] },
|
| - { " r14: ", context->uc_mcontext.gregs[REG_R14] },
|
| - { " r15: ", context->uc_mcontext.gregs[REG_R15] },
|
| - { " di: ", context->uc_mcontext.gregs[REG_RDI] },
|
| - { " si: ", context->uc_mcontext.gregs[REG_RSI] },
|
| - { " bp: ", context->uc_mcontext.gregs[REG_RBP] },
|
| - { " bx: ", context->uc_mcontext.gregs[REG_RBX] },
|
| - { " dx: ", context->uc_mcontext.gregs[REG_RDX] },
|
| - { " ax: ", context->uc_mcontext.gregs[REG_RAX] },
|
| - { " cx: ", context->uc_mcontext.gregs[REG_RCX] },
|
| - { " sp: ", context->uc_mcontext.gregs[REG_RSP] },
|
| - { " ip: ", context->uc_mcontext.gregs[REG_RIP] },
|
| - { " efl: ", context->uc_mcontext.gregs[REG_EFL] },
|
| - { " cgf: ", context->uc_mcontext.gregs[REG_CSGSFS] },
|
| - { " erf: ", context->uc_mcontext.gregs[REG_ERR] },
|
| - { " trp: ", context->uc_mcontext.gregs[REG_TRAPNO] },
|
| - { " msk: ", context->uc_mcontext.gregs[REG_OLDMASK] },
|
| - { " cr2: ", context->uc_mcontext.gregs[REG_CR2] },
|
| + { "r8", context->uc_mcontext.gregs[REG_R8] },
|
| + { "r9", context->uc_mcontext.gregs[REG_R9] },
|
| + { "r10", context->uc_mcontext.gregs[REG_R10] },
|
| + { "r11", context->uc_mcontext.gregs[REG_R11] },
|
| + { "r12", context->uc_mcontext.gregs[REG_R12] },
|
| + { "r13", context->uc_mcontext.gregs[REG_R13] },
|
| + { "r14", context->uc_mcontext.gregs[REG_R14] },
|
| + { "r15", context->uc_mcontext.gregs[REG_R15] },
|
| + { "di", context->uc_mcontext.gregs[REG_RDI] },
|
| + { "si", context->uc_mcontext.gregs[REG_RSI] },
|
| + { "bp", context->uc_mcontext.gregs[REG_RBP] },
|
| + { "bx", context->uc_mcontext.gregs[REG_RBX] },
|
| + { "dx", context->uc_mcontext.gregs[REG_RDX] },
|
| + { "ax", context->uc_mcontext.gregs[REG_RAX] },
|
| + { "cx", context->uc_mcontext.gregs[REG_RCX] },
|
| + { "sp", context->uc_mcontext.gregs[REG_RSP] },
|
| + { "ip", context->uc_mcontext.gregs[REG_RIP] },
|
| + { "efl", context->uc_mcontext.gregs[REG_EFL] },
|
| + { "cgf", context->uc_mcontext.gregs[REG_CSGSFS] },
|
| + { "erf", context->uc_mcontext.gregs[REG_ERR] },
|
| + { "trp", context->uc_mcontext.gregs[REG_TRAPNO] },
|
| + { "msk", context->uc_mcontext.gregs[REG_OLDMASK] },
|
| + { "cr2", context->uc_mcontext.gregs[REG_CR2] },
|
| #endif
|
| };
|
|
|
| #if ARCH_CPU_32_BITS
|
| - const int kRegisterPadding = 8;
|
| + #define K_REGISTER_PADDING "8"
|
| #elif ARCH_CPU_64_BITS
|
| - const int kRegisterPadding = 16;
|
| + #define K_REGISTER_PADDING "16"
|
| #endif
|
|
|
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(registers); i++) {
|
| - PrintToStderr(registers[i].label);
|
| - internal::itoa_r(registers[i].value, buf, sizeof(buf),
|
| - 16, kRegisterPadding);
|
| + Format(buf, "%4s: %"K_REGISTER_PADDING"x%s",
|
| + registers[i].label,
|
| + registers[i].value,
|
| + (i + 1) % 4 == 0 ? "\n" : "");
|
| PrintToStderr(buf);
|
| -
|
| - if ((i + 1) % 4 == 0)
|
| - PrintToStderr("\n");
|
| }
|
| PrintToStderr("\n");
|
| #endif
|
| @@ -487,70 +481,5 @@ void StackTrace::OutputToStream(std::ostream* os) const {
|
| ProcessBacktrace(trace_, count_, &handler);
|
| }
|
|
|
| -namespace internal {
|
| -
|
| -// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
|
| -char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) {
|
| - // Make sure we can write at least one NUL byte.
|
| - size_t n = 1;
|
| - if (n > sz)
|
| - return NULL;
|
| -
|
| - if (base < 2 || base > 16) {
|
| - buf[0] = '\000';
|
| - return NULL;
|
| - }
|
| -
|
| - char *start = buf;
|
| -
|
| - uintptr_t j = i;
|
| -
|
| - // Handle negative numbers (only for base 10).
|
| - if (i < 0 && base == 10) {
|
| - j = -i;
|
| -
|
| - // Make sure we can write the '-' character.
|
| - if (++n > sz) {
|
| - buf[0] = '\000';
|
| - return NULL;
|
| - }
|
| - *start++ = '-';
|
| - }
|
| -
|
| - // Loop until we have converted the entire number. Output at least one
|
| - // character (i.e. '0').
|
| - char *ptr = start;
|
| - do {
|
| - // Make sure there is still enough space left in our output buffer.
|
| - if (++n > sz) {
|
| - buf[0] = '\000';
|
| - return NULL;
|
| - }
|
| -
|
| - // Output the next digit.
|
| - *ptr++ = "0123456789abcdef"[j % base];
|
| - j /= base;
|
| -
|
| - if (padding > 0)
|
| - padding--;
|
| - } while (j > 0 || padding > 0);
|
| -
|
| - // Terminate the output with a NUL character.
|
| - *ptr = '\000';
|
| -
|
| - // Conversion to ASCII actually resulted in the digits being in reverse
|
| - // order. We can't easily generate them in forward order, as we can't tell
|
| - // the number of characters needed until we are done converting.
|
| - // So, now, we reverse the string (except for the possible "-" sign).
|
| - while (--ptr > start) {
|
| - char ch = *ptr;
|
| - *ptr = *start;
|
| - *start++ = ch;
|
| - }
|
| - return buf;
|
| -}
|
| -
|
| -} // namespace internal
|
| -
|
| } // namespace debug
|
| } // namespace base
|
|
|