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

Unified Diff: base/debug/stack_trace.cc

Issue 1975393002: Check stack pointer to be inside stack when unwinding. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Revert to the LGTMed patchset 1 Created 4 years, 6 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 | « no previous file | no next file » | 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..ac0ead76be2b1cf62339e55fa20b59f6488acbe9 100644
--- a/base/debug/stack_trace.cc
+++ b/base/debug/stack_trace.cc
@@ -11,6 +11,12 @@
#include "base/macros.h"
+#if HAVE_TRACE_STACK_FRAME_POINTERS && defined(OS_ANDROID)
+#include <pthread.h>
+#include "base/process/process_handle.h"
+#include "base/threading/platform_thread.h"
+#endif
+
namespace base {
namespace debug {
@@ -41,6 +47,44 @@ std::string StackTrace::ToString() const {
#if HAVE_TRACE_STACK_FRAME_POINTERS
+#if defined(OS_ANDROID)
+
+static uintptr_t GetStackEnd() {
+ // Bionic reads proc/maps on every call to pthread_getattr_np() when called
+ // from the main thread. So we need to cache end of stack in that case to get
+ // acceptable performance.
+ // For all other threads pthread_getattr_np() is fast enough as it just reads
+ // values from its pthread_t argument.
+ static uintptr_t main_stack_end = 0;
+
+ bool is_main_thread = GetCurrentProcId() == PlatformThread::CurrentId();
+
+ if (is_main_thread && main_stack_end) {
+ return main_stack_end;
+ }
+
+ uintptr_t stack_begin = 0;
+ size_t stack_size = 0;
+ pthread_attr_t attributes;
+ int error = pthread_getattr_np(pthread_self(), &attributes);
+ if (!error) {
+ error = pthread_attr_getstack(
+ &attributes,
+ reinterpret_cast<void**>(&stack_begin),
+ &stack_size);
+ pthread_attr_destroy(&attributes);
+ }
+ DCHECK(!error);
+
+ uintptr_t stack_end = stack_begin + stack_size;
+ if (is_main_thread) {
+ main_stack_end = stack_end;
+ }
+ return stack_end;
+}
+
+#endif // defined(OS_ANDROID)
+
size_t TraceStackFramePointers(const void** out_trace,
size_t max_depth,
size_t skip_initial) {
@@ -49,6 +93,10 @@ size_t TraceStackFramePointers(const void** out_trace,
// be valid.
uintptr_t sp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
+#if defined(OS_ANDROID)
+ uintptr_t stack_end = GetStackEnd();
+#endif
+
size_t depth = 0;
while (depth < max_depth) {
#if defined(__arm__) && defined(__GNUC__) && !defined(__clang__)
@@ -58,6 +106,13 @@ size_t TraceStackFramePointers(const void** out_trace,
sp -= sizeof(uintptr_t);
#endif
+#if defined(OS_ANDROID)
+ // Both sp[0] and s[1] must be valid.
+ if (sp + 2 * sizeof(uintptr_t) > stack_end) {
+ break;
+ }
+#endif
+
if (skip_initial != 0) {
skip_initial--;
} else {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698