diff options
Diffstat (limited to 'compiler-rt')
3 files changed, 54 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index 858a881d0d3..ff6acc6f48a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -165,6 +165,11 @@ COMMON_FLAG(bool, symbolize_inline_frames, true, COMMON_FLAG(bool, symbolize_vs_style, false, "Print file locations in Visual Studio style (e.g: " " file(10,42): ...") +COMMON_FLAG(int, dedup_token_length, 0, + "If positive, after printing a stack trace also print a short " + "string token based on this number of frames that will simplify " + "deduplication of the reports. " + "Example: 'DEDUP_TOKEN: foo-bar-main'. Default is 0.") COMMON_FLAG(const char *, stack_trace_format, "DEFAULT", "Format string used to render stack frames. " "See sanitizer_stacktrace_printer.h for the format description. " diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc index f66fa79f19a..59ca927fa5b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc @@ -25,6 +25,8 @@ void StackTrace::Print() const { return; } InternalScopedString frame_desc(GetPageSizeCached() * 2); + InternalScopedString dedup_token(GetPageSizeCached()); + int dedup_frames = common_flags()->dedup_token_length; uptr frame_num = 0; for (uptr i = 0; i < size && trace[i]; i++) { // PCs in stack traces are actually the return addresses, that is, @@ -38,11 +40,18 @@ void StackTrace::Print() const { cur->info, common_flags()->symbolize_vs_style, common_flags()->strip_path_prefix); Printf("%s\n", frame_desc.data()); + if (dedup_frames-- > 0) { + if (dedup_token.length()) + dedup_token.append("--"); + dedup_token.append(cur->info.function); + } } frames->ClearAll(); } // Always print a trailing empty line after stack trace. Printf("\n"); + if (dedup_token.length()) + Printf("DEDUP_TOKEN: %s\n", dedup_token.data()); } void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context, diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc new file mode 100644 index 00000000000..35409f65e98 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc @@ -0,0 +1,40 @@ +// Test dedup_token_length +// RUN: %clangxx -O0 %s -o %t +// RUN: env %tool_options='' not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: env %tool_options='dedup_token_length=0' not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: env %tool_options='dedup_token_length=1' not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: env %tool_options='dedup_token_length=2' not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: env %tool_options='dedup_token_length=3' not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 + +// REQUIRES: stable-runtime +// FIXME: implement SEGV handler in other sanitizers, not just asan. +// XFAIL: msan +// XFAIL: lsan +// XFAIL: tsan + +volatile int *null = 0; + +namespace Xyz { + template<class A, class B> void Abc() { + *null = 0; + } +} + +extern "C" void bar() { + Xyz::Abc<int, int>(); +} + +void FOO() { + bar(); +} + +int main(int argc, char **argv) { + FOO(); +} + +// CHECK0-NOT: DEDUP_TOKEN: +// CHECK1: DEDUP_TOKEN: void Xyz::Abc<int, int>() +// CHECK1-NOT: bar +// CHECK2: DEDUP_TOKEN: void Xyz::Abc<int, int>()--bar +// CHECK2-NOT: FOO +// CHECK3: DEDUP_TOKEN: void Xyz::Abc<int, int>()--bar--FOO() |

