summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2018-10-02 00:29:41 +0000
committerVitaly Buka <vitalybuka@google.com>2018-10-02 00:29:41 +0000
commitae1bbea8906622d2863c0e65e51f0028c2a7613a (patch)
tree7d413ffdacf67de4002f1a5fb74b9a0ed342ede1
parent99d4f74d01c2bb88a2786bf41e972a3a4a7f1e6c (diff)
downloadbcm5719-llvm-ae1bbea8906622d2863c0e65e51f0028c2a7613a.tar.gz
bcm5719-llvm-ae1bbea8906622d2863c0e65e51f0028c2a7613a.zip
[sanitizer] Include inlined frames into __sanitizer_symbolize_pc output
Summary: Behavior for existing used is not changing as the first line is going to be the same, and it was invalid to try to read more lines. New clients can read until they get empty string. Reviewers: eugenis, morehouse Subscribers: kubamracek, eraman, llvm-commits Differential Revision: https://reviews.llvm.org/D52743 llvm-svn: 343554
-rw-r--r--compiler-rt/include/sanitizer/common_interface_defs.h6
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc24
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cc30
3 files changed, 55 insertions, 5 deletions
diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h
index d11cb1addc2..bf015eb237c 100644
--- a/compiler-rt/include/sanitizer/common_interface_defs.h
+++ b/compiler-rt/include/sanitizer/common_interface_defs.h
@@ -124,6 +124,12 @@ extern "C" {
// Symbolizes the supplied 'pc' using the format string 'fmt'.
// Outputs at most 'out_buf_size' bytes into 'out_buf'.
+ // If 'out_buf' is not empty then output is zero or more non empty C strings
+ // followed by single empty C string. Multiple strings can be returned if PC
+ // corresponds to inlined function. Inlined frames are printed in the order
+ // from "most-inlined" to the "least-inlined", so the last frame should be the
+ // not inlined function.
+ // Inlined frames can be removed with 'symbolize_inline_frames=0'.
// The format syntax is described in
// lib/sanitizer_common/sanitizer_stacktrace_printer.h.
void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
index 747a4a70172..c87b18e1b69 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
@@ -114,11 +114,25 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
return;
}
InternalScopedString frame_desc(GetPageSizeCached());
- RenderFrame(&frame_desc, fmt, 0, frame->info,
- common_flags()->symbolize_vs_style,
- common_flags()->strip_path_prefix);
- internal_strncpy(out_buf, frame_desc.data(), out_buf_size);
- out_buf[out_buf_size - 1] = 0;
+ uptr frame_num = 0;
+ // Reserve one byte for the final 0.
+ char *out_end = out_buf + out_buf_size - 1;
+ for (SymbolizedStack *cur = frame; cur && out_buf < out_end;
+ cur = cur->next) {
+ frame_desc.clear();
+ RenderFrame(&frame_desc, fmt, frame_num++, cur->info,
+ common_flags()->symbolize_vs_style,
+ common_flags()->strip_path_prefix);
+ if (!frame_desc.length())
+ continue;
+ // Reserve one byte for the terminating 0.
+ uptr n = out_end - out_buf - 1;
+ internal_strncpy(out_buf, frame_desc.data(), n);
+ out_buf += __sanitizer::Min<uptr>(n, frame_desc.length());
+ *out_buf++ = 0;
+ }
+ CHECK(out_buf <= out_end);
+ *out_buf = 0;
}
SANITIZER_INTERFACE_ATTRIBUTE
diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cc b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cc
new file mode 100644
index 00000000000..bd89aa6e2d2
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx -O3 %s -o %t
+// RUN: %env_tool_opts=strip_path_prefix=/TestCases/ %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=strip_path_prefix=/TestCases/:symbolize_inline_frames=0 \
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-NOINLINE
+
+#include <sanitizer/common_interface_defs.h>
+#include <stdio.h>
+#include <string.h>
+
+char buffer[10000];
+
+__attribute__((noinline)) static void Symbolize() {
+ __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", buffer,
+ sizeof(buffer));
+ for (char *p = buffer; strlen(p); p += strlen(p) + 1)
+ printf("%s\n", p);
+}
+
+// CHECK-NOINLINE: {{0x[0-9a-f]+}} in main symbolize_pc_inline.cc:[[@LINE+2]]
+// CHECK: [[ADDR:0x[0-9a-f]+]] in C2 symbolize_pc_inline.cc:[[@LINE+1]]
+static inline void C2() { Symbolize(); }
+
+// CHECK: [[ADDR]] in C3 symbolize_pc_inline.cc:[[@LINE+1]]
+static inline void C3() { C2(); }
+
+// CHECK: [[ADDR]] in C4 symbolize_pc_inline.cc:[[@LINE+1]]
+static inline void C4() { C3(); }
+
+// CHECK: [[ADDR]] in main symbolize_pc_inline.cc:[[@LINE+1]]
+int main() { C4(); }
OpenPOWER on IntegriCloud