summaryrefslogtreecommitdiffstats
path: root/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h')
-rw-r--r--third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h45
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;
}