Index: base/debug/stack_trace_android.cc |
diff --git a/base/debug/stack_trace_android.cc b/base/debug/stack_trace_android.cc |
index 050a2d8c501904b17e3bee5cf13993fafd639026..ab19ee198cefebfa4bbe5864d8ffcbb0d046a08a 100644 |
--- a/base/debug/stack_trace_android.cc |
+++ b/base/debug/stack_trace_android.cc |
@@ -8,8 +8,10 @@ |
#include <sys/types.h> |
#include <unistd.h> |
#include <unwind.h> // TODO(dmikurube): Remove. See http://crbug.com/236855. |
+#include <iomanip> |
-#include "base/logging.h" |
+#include "base/third_party/symbolize/demangle.h" |
+#include "base/third_party/symbolize/symbolize.h" |
#ifdef __MIPSEL__ |
// SIGSTKFLT is not defined for MIPS. |
@@ -117,8 +119,53 @@ void StackTrace::PrintBacktrace() const { |
signal(SIGSTKFLT, sig_handler); |
} |
+static int OnSymbolizeCallback(int fd, |
+ void* pc, |
+ char* out, |
+ size_t out_size, |
+ uint64 relocation) { |
+ // Maximum string length of an int is 10 characters. |
+ char path[32]; |
+ int size = snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); |
+ if (size < 0 || static_cast<size_t>(size) >= sizeof(path)) |
+ return -1; |
+ |
+ char buf[1024]; |
+ size = readlink(path, buf, sizeof(buf)); |
scherkus (not reviewing)
2013/06/12 00:43:43
satorux: this is also kind of unnecessary since sy
satorux1
2013/06/12 05:43:42
I think it's easy to change symbolize.cc to provid
|
+ if (size < 0 || static_cast<size_t>(size) >= sizeof(buf)) |
+ return -1; |
+ buf[size] = '\0'; // readlink() doesn't null-terminate strings. |
+ |
+ uintptr_t rel_pc = reinterpret_cast<uintptr_t>(pc) - relocation; |
+ size = snprintf(out, out_size, "pc %08x %s ", rel_pc, buf); |
+ return size; |
+} |
+ |
void StackTrace::OutputToStream(std::ostream* os) const { |
- NOTIMPLEMENTED(); |
+ // TODO(scherkus): HACK - is this thread/async safe and/or proper usage? |
+ google::InstallSymbolizeCallback(&OnSymbolizeCallback); |
scherkus (not reviewing)
2013/06/12 00:43:43
satorux: is this intended usage? I couldn't find a
satorux1
2013/06/12 05:43:42
IIRC, this awkward callback hook was introduced to
|
+ |
+ for (size_t i = 0; i < count_; ++i) { |
+ // NOTE: Native libraries in APKs are stripped before installing. Print out |
+ // the relocatable address and library names so host computers can use tools |
+ // to symbolize and demangle (e.g., addr2line, c++filt). |
+ char buf[1024]; |
+ strncpy(buf, "<unknown>", sizeof(buf)); |
+ |
+ // Subtract by one as return address of function may be in the next |
+ // function when a function is annotated as noreturn. |
+ void* address = static_cast<char*>(trace_[i]) - 1; |
+ google::Symbolize(address, buf, sizeof(buf)); |
+ |
+ // TODO(scherkus): HACK - we blindly print contents of |buf| knowing that |
scherkus (not reviewing)
2013/06/12 00:43:43
satorux: this is also really gross
I want to use
satorux1
2013/06/12 05:43:42
If Symbolize() fails most of the time, using this
scherkus (not reviewing)
2013/06/13 01:27:44
I went with (2) -- let me know if you think it's t
|
+ // it's initialized to "<unknown>" and that our callback will be executed to |
+ // fill the contents with the executable path and offset. |
+ |
+ *os << " #" << std::setfill('0') << std::setw(2) << i << " " << buf |
+ << "\n"; |
+ } |
+ |
+ google::InstallSymbolizeCallback(NULL); |
} |
} // namespace debug |