Index: third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h |
=================================================================== |
--- third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h (revision 57513) |
+++ third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h (working copy) |
@@ -65,6 +65,9 @@ |
#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 @@ |
#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 @@ |
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 @@ |
#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; |
} |