Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[compiler-rt] Don't reset non-default user handler if allow_user_segv…
…_handler is true. Reviewers: eugenis, kcc Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D32457 llvm-svn: 304039
- Loading branch information
1 parent
ac4307c
commit e8b0919
Showing
2 changed files
with
124 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
compiler-rt/test/asan/TestCases/Linux/preinstalled_signal.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// clang-format off | ||
// RUN: %clangxx -std=c++11 %s -o %t | ||
// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s | ||
// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s | ||
|
||
// RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_HANDLER %s -o %t | ||
// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-HANDLER %s | ||
// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s | ||
|
||
// RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_ACTION %s -o %t | ||
// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ACTION %s | ||
// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s | ||
|
||
// REQUIRES: asan-dynamic-runtime | ||
|
||
// This way of setting LD_PRELOAD does not work with Android test runner. | ||
// REQUIRES: not-android | ||
// clang-format on | ||
|
||
#include <assert.h> | ||
#include <signal.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/syscall.h> | ||
#include <unistd.h> | ||
|
||
const char *handler = nullptr; | ||
void SigHandler(int signum) { handler = "TestSigHandler"; } | ||
void SigAction(int, siginfo_t *, void *) { handler = "TestSigAction"; } | ||
|
||
struct KernelSigaction { | ||
__sighandler_t handler; | ||
unsigned long flags; | ||
void (*restorer)(); | ||
char unused[1024]; | ||
}; | ||
|
||
#if defined(__x86_64__) | ||
extern "C" void restorer(); | ||
asm("restorer:mov $15,%rax\nsyscall"); | ||
#endif | ||
|
||
int InternalSigaction(int sig, KernelSigaction *act, KernelSigaction *oact) { | ||
if (act) { | ||
#if defined(__x86_64__) | ||
act->flags |= 0x04000000; | ||
act->restorer = &restorer; | ||
#endif | ||
} | ||
return syscall(__NR_rt_sigaction, sig, act, oact, NSIG / 8); | ||
} | ||
|
||
struct KernelSigaction sigact = {}; | ||
|
||
static void Init() { | ||
int res = InternalSigaction(SIGSEGV, nullptr, &sigact); | ||
assert(res >= 0); | ||
assert(sigact.handler == SIG_DFL || sigact.handler == SIG_IGN); | ||
#if defined(TEST_INSTALL_SIG_HANDLER) | ||
sigact = {}; | ||
sigact.handler = &SigHandler; | ||
res = InternalSigaction(SIGSEGV, &sigact, nullptr); | ||
assert(res >= 0); | ||
#elif defined(TEST_INSTALL_SIG_ACTION) | ||
sigact = {}; | ||
sigact.flags = SA_SIGINFO | SA_NODEFER; | ||
sigact.handler = (__sighandler_t)&SigAction; | ||
res = InternalSigaction(SIGSEGV, &sigact, nullptr); | ||
assert(res >= 0); | ||
#endif | ||
} | ||
|
||
__attribute__((section(".preinit_array"), used)) | ||
void (*__local_test_preinit)(void) = Init; | ||
|
||
bool ShouldAsanInstallHandlers() { | ||
#if defined(TEST_INSTALL_SIG_HANDLER) || defined(TEST_INSTALL_SIG_ACTION) | ||
return !strcmp(getenv("ASAN_OPTIONS"), "handle_segv=2"); | ||
#endif | ||
return true; | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
KernelSigaction sigact_asan = {}; | ||
InternalSigaction(SIGSEGV, nullptr, &sigact_asan); | ||
|
||
assert(sigact_asan.handler != SIG_DFL); | ||
assert(sigact_asan.handler != SIG_IGN); | ||
assert(ShouldAsanInstallHandlers() == | ||
(sigact_asan.handler != sigact.handler)); | ||
|
||
raise(SIGSEGV); | ||
printf("%s\n", handler); | ||
return 1; | ||
} | ||
|
||
// CHECK-NOT: TestSig | ||
// CHECK: ASAN:DEADLYSIGNAL | ||
|
||
// CHECK-HANDLER-NOT: ASAN:DEADLYSIGNAL | ||
// CHECK-HANDLER: TestSigHandler | ||
|
||
// CHECK-ACTION-NOT: ASAN:DEADLYSIGNAL | ||
// CHECK-ACTION: TestSigAction |