From 177d0c91d6f86adfca2f466141c7a4532209935f Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Wed, 2 Oct 2019 21:20:37 +0000 Subject: [compiler-rt] Use GetNextInstructionPc in signal handlers Summary: All other stack trace callers assume that PC contains return address. HWAsan already use GetNextInstructionPc in similar code. PR43339 Reviewers: eugenis, kcc, jfb Subscribers: dexonsmith, dberris, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D68313 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@373529 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/asan/asan_errors.cpp | 3 +- lib/lsan/lsan.cpp | 2 +- lib/msan/msan.cpp | 2 +- lib/tsan/rtl/tsan_rtl.cpp | 2 +- lib/ubsan/ubsan_signals_standalone.cpp | 5 +-- .../TestCases/Linux/signal_line.cpp | 36 ++++++++++++++++++++++ 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 test/sanitizer_common/TestCases/Linux/signal_line.cpp diff --git a/lib/asan/asan_errors.cpp b/lib/asan/asan_errors.cpp index 0ef97794b..541c6e035 100644 --- a/lib/asan/asan_errors.cpp +++ b/lib/asan/asan_errors.cpp @@ -35,7 +35,8 @@ static void OnStackUnwind(const SignalContext &sig, // corresponding code in the sanitizer_common and we use this callback to // print it. static_cast(callback_context)->Print(); - stack->Unwind(sig.pc, sig.bp, sig.context, fast); + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, + fast); } void ErrorDeadlySignal::Print() { diff --git a/lib/lsan/lsan.cpp b/lib/lsan/lsan.cpp index deabf044a..4ce03046f 100644 --- a/lib/lsan/lsan.cpp +++ b/lib/lsan/lsan.cpp @@ -89,7 +89,7 @@ static void InitializeFlags() { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } diff --git a/lib/msan/msan.cpp b/lib/msan/msan.cpp index da3534bc5..6ea63cb2c 100644 --- a/lib/msan/msan.cpp +++ b/lib/msan/msan.cpp @@ -378,7 +378,7 @@ void __msan_warning_noreturn() { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } diff --git a/lib/tsan/rtl/tsan_rtl.cpp b/lib/tsan/rtl/tsan_rtl.cpp index 39b9cea52..3f3c0cce1 100644 --- a/lib/tsan/rtl/tsan_rtl.cpp +++ b/lib/tsan/rtl/tsan_rtl.cpp @@ -338,7 +338,7 @@ static void CheckShadowMapping() { #if !SANITIZER_GO static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } diff --git a/lib/ubsan/ubsan_signals_standalone.cpp b/lib/ubsan/ubsan_signals_standalone.cpp index 627b3c4d8..2c91db8ca 100644 --- a/lib/ubsan/ubsan_signals_standalone.cpp +++ b/lib/ubsan/ubsan_signals_standalone.cpp @@ -45,8 +45,9 @@ namespace __ubsan { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - ubsan_GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, - common_flags()->fast_unwind_on_fatal); + ubsan_GetStackTrace(stack, kStackTraceMax, + StackTrace::GetNextInstructionPc(sig.pc), sig.bp, + sig.context, common_flags()->fast_unwind_on_fatal); } static void UBsanOnDeadlySignal(int signo, void *siginfo, void *context) { diff --git a/test/sanitizer_common/TestCases/Linux/signal_line.cpp b/test/sanitizer_common/TestCases/Linux/signal_line.cpp new file mode 100644 index 000000000..57175effe --- /dev/null +++ b/test/sanitizer_common/TestCases/Linux/signal_line.cpp @@ -0,0 +1,36 @@ +// Test line numbers in signal handlers + +// RUN: %clangxx %s -o %t -O0 +// RUN: %env_tool_opts=handle_segv=1:print_stacktrace=1 not %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK1,CHECK %s +// RUN: %env_tool_opts=handle_segv=1:print_stacktrace=1 not %run %t 2 2>&1 | FileCheck --check-prefixes=CHECK2,CHECK %s +// RUN: %env_tool_opts=handle_segv=1:print_stacktrace=1 not %run %t 3 2>&1 | FileCheck --check-prefixes=CHECK3,CHECK %s +// RUN: %env_tool_opts=handle_segv=1:print_stacktrace=1 not %run %t 4 2>&1 | FileCheck --check-prefixes=CHECK4,CHECK %s + +#include +#include + +// CHECK: [[SAN:.*Sanitizer]]:DEADLYSIGNAL +// CHECK: ERROR: [[SAN]]: SEGV on unknown address {{0x[^ ]*}} (pc +int main(int argc, char **argv) { + int n = atoi(argv[1]); + + if (n == 1) + *((volatile int *)0x0) = __LINE__; + // CHECK1: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]] + // CHECK1: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main + + if (n == 2) + *((volatile int *)0x0) = __LINE__; + // CHECK2: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]] + // CHECK2: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main + + if (n == 3) + *((volatile int *)0x0) = __LINE__; + // CHECK3: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]] + // CHECK3: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main + + if (n == 4) + *((volatile int *)0x0) = __LINE__; + // CHECK4: #{{[0-9]+ .*}}main {{.*}}signal_line.cpp:[[@LINE-1]]:[[TAB:[0-9]+]] + // CHECK4: SUMMARY: [[SAN]]: SEGV {{.*}}signal_line.cpp:[[@LINE-2]]:[[TAB]] in main +} -- cgit v1.2.1