Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2949)

Unified Diff: base/debug/stack_trace.cc

Issue 1996243002: Workaround ARM tracing issues for non-component builds. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/third_party/symbolize/symbolize.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/debug/stack_trace.cc
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc
index 1c96a569d9795544231714f0d0b1f9b0da036355..70a960470569026e02d4b0e1ebd660a497a3876d 100644
--- a/base/debug/stack_trace.cc
+++ b/base/debug/stack_trace.cc
@@ -10,6 +10,7 @@
#include <sstream>
#include "base/macros.h"
+#include "base/third_party/symbolize/symbolize.h"
namespace base {
namespace debug {
@@ -41,9 +42,61 @@ std::string StackTrace::ToString() const {
#if HAVE_TRACE_STACK_FRAME_POINTERS
+#if defined(OS_ANDROID) && !defined(COMPONENT_BUILD)
+
+#define HAVE_CHROME_CODE_RANGE
+
+bool FindChromeCodeRange(const void** out_start_address,
+ const void** out_end_address) {
+ struct FindArgs {
+ const void** out_start_address;
+ const void** out_end_address;
+ };
+
+ auto find_callback = [](void* data,
+ const google::MappedRegion& region) -> bool {
+ const void* region_start_address = reinterpret_cast<const void*>(
+ static_cast<uintptr_t>(region.start_address));
+ const void* region_end_address = reinterpret_cast<const void*>(
+ static_cast<uintptr_t>(region.end_address));
+
+ const void* self_address = reinterpret_cast<const void*>(
+ &FindChromeCodeRange);
+ if (self_address >= region_start_address &&
+ self_address < region_end_address) {
+ FindArgs* args = static_cast<FindArgs*>(data);
+ *args->out_start_address = region_start_address;
+ *args->out_end_address = region_end_address;
+ return true;
+ }
+
+ return false;
+ };
+
+ FindArgs args = {
+ out_start_address,
+ out_end_address
+ };
+ return google::FindMappedRegion(&args, find_callback);
+}
+
+#endif // !defined(COMPONENT_BUILD)
+
size_t TraceStackFramePointers(const void** out_trace,
size_t max_depth,
size_t skip_initial) {
+#if defined(HAVE_CHROME_CODE_RANGE)
+ static const void* chrome_code_start = 0;
+ static const void* chrome_code_end = 0;
+ if (!chrome_code_start || !chrome_code_end) {
+ if (!FindChromeCodeRange(&chrome_code_start, &chrome_code_end)) {
+ // Something went wrong; disable unwinding.
+ chrome_code_start = reinterpret_cast<const void*>(UINTPTR_MAX);
+ chrome_code_end = reinterpret_cast<const void*>(UINTPTR_MAX);
+ }
+ }
+#endif
+
// Usage of __builtin_frame_address() enables frame pointers in this
// function even if they are not enabled globally. So 'sp' will always
// be valid.
@@ -61,7 +114,42 @@ size_t TraceStackFramePointers(const void** out_trace,
if (skip_initial != 0) {
skip_initial--;
} else {
- out_trace[depth++] = reinterpret_cast<const void**>(sp)[1];
+#if defined(HAVE_CHROME_CODE_RANGE) && \
+ defined(__clang__) && defined(__thumb__)
+
+ // In thumb fp is r7 and lr is r14, so there can be 1-7 registers
+ // in between.
+ const void* pc;
+ for (size_t i = 1; i <= 7; ++i) {
+ pc = reinterpret_cast<const void**>(sp)[i];
+ if (pc >= chrome_code_start && pc < chrome_code_end) {
+ // Looks like code, use it.
+ break;
+ }
+ pc = nullptr;
+ }
+ if (!pc) {
+ // Didn't find anything, stop unwinding.
+ break;
+ }
+ out_trace[depth++] = pc;
+
+#else
+
+ // In arm mode we have proper stack frames, so lr always follows fp.
+ const void* pc = reinterpret_cast<const void**>(sp)[1];
+ out_trace[depth++] = pc;
+#if defined(HAVE_CHROME_CODE_RANGE)
+ if (pc < chrome_code_start || pc >= chrome_code_end) {
+ // Stop unwinding after first non-Chrome PC - it's either bogus,
+ // or from a system library. But since system libraries on Android
+ // and Linux are built without frame pointers, there is no point
+ // diving into them.
+ break;
+ }
+#endif
+
+#endif // HAVE_CHROME_CODE_RANGE && __clang__ && __thumb__
}
// Find out next frame pointer
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/third_party/symbolize/symbolize.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698