diff options
Diffstat (limited to 'third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h')
-rw-r--r-- | third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h index a140ab6..0f8c4de 100644 --- a/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h +++ b/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h @@ -65,6 +65,9 @@ typedef ucontext ucontext_t; #endif #include "google/stacktrace.h" +#if defined(KEEP_SHADOW_STACKS) +#include "linux_shadow_stacks.h" +#endif // KEEP_SHADOW_STACKS #if defined(__linux__) && defined(__i386__) && defined(__ELF__) && defined(HAVE_MMAP) // Count "push %reg" instructions in VDSO __kernel_vsyscall(), @@ -316,6 +319,21 @@ int GET_STACK_TRACE_OR_FRAMES { #endif int n = 0; +#if defined(KEEP_SHADOW_STACKS) + void **shadow_ip_stack; + void **shadow_sp_stack; + int stack_size; + shadow_ip_stack = (void**) get_shadow_ip_stack(&stack_size); + shadow_sp_stack = (void**) get_shadow_sp_stack(&stack_size); + int shadow_index = stack_size - 1; + for (int i = stack_size - 1; i >= 0; i--) { + if (sp == shadow_sp_stack[i]) { + shadow_index = i; + break; + } + } + void **prev_sp = NULL; +#endif // KEEP_SHADOW_STACKS while (sp && n < max_depth) { if (*(sp+1) == reinterpret_cast<void *>(0)) { // In 64-bit code, we often see a frame that @@ -328,8 +346,17 @@ int GET_STACK_TRACE_OR_FRAMES { void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp); if (skip_count > 0) { skip_count--; +#if defined(KEEP_SHADOW_STACKS) + shadow_index--; +#endif // KEEP_SHADOW_STACKS } else { result[n] = *(sp+1); +#if defined(KEEP_SHADOW_STACKS) + if ((shadow_index > 0) && (sp == shadow_sp_stack[shadow_index])) { + shadow_index--; + } +#endif // KEEP_SHADOW_STACKS + #if IS_STACK_FRAMES if (next_sp > sp) { sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp; @@ -340,7 +367,25 @@ int GET_STACK_TRACE_OR_FRAMES { #endif n++; } +#if defined(KEEP_SHADOW_STACKS) + prev_sp = sp; +#endif // KEEP_SHADOW_STACKS sp = next_sp; } + +#if defined(KEEP_SHADOW_STACKS) + if (shadow_index >= 0) { + for (int i = shadow_index; i >= 0; i--) { + if (shadow_sp_stack[i] > prev_sp) { + result[n] = shadow_ip_stack[i]; + if (n + 1 < max_depth) { + n++; + continue; + } + } + break; + } + } +#endif // KEEP_SHADOW_STACKS return n; } |