[asan] introduce __sanitizer_set_death_callback, deprecate __asan_set_death_callback

llvm-svn: 224286
This commit is contained in:
Kostya Serebryany 2014-12-15 23:02:57 +00:00
parent 4555b6d870
commit 42102b110e
6 changed files with 70 additions and 12 deletions

View File

@ -114,8 +114,7 @@ extern "C" {
// Returns the old value.
int __asan_set_error_exit_code(int exit_code);
// Sets the callback to be called right before death on error.
// Passing 0 will unset the callback.
// Deprecated. Call __sanitizer_set_death_callback instead.
void __asan_set_death_callback(void (*callback)(void));
void __asan_set_error_report_callback(void (*callback)(const char*));

View File

@ -120,6 +120,9 @@ extern "C" {
// Print the stack trace leading to this call. Useful for debugging user code.
void __sanitizer_print_stack_trace();
// Sets the callback to be called right before death on error.
// Passing 0 will unset the callback.
void __sanitizer_set_death_callback(void (*callback)(void));
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -56,8 +56,6 @@ static void AsanDie() {
}
if (common_flags()->coverage)
__sanitizer_cov_dump();
if (death_callback)
death_callback();
if (flags()->abort_on_error)
Abort();
internal__exit(flags()->exitcode);
@ -341,7 +339,6 @@ void ParseExtraActivationFlags() {
// -------------------------- Globals --------------------- {{{1
int asan_inited;
bool asan_init_is_running;
void (*death_callback)(void);
#if !ASAN_FIXED_MAPPING
uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
@ -767,7 +764,7 @@ void NOINLINE __asan_handle_no_return() {
}
void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
death_callback = callback;
SetUserDieCallback(callback);
}
// Initialize as requested from instrumented application code.

View File

@ -94,19 +94,23 @@ uptr stoptheworld_tracer_pid = 0;
// writing to the same log file.
uptr stoptheworld_tracer_ppid = 0;
static DieCallbackType DieCallback;
static DieCallbackType InternalDieCallback, UserDieCallback;
void SetDieCallback(DieCallbackType callback) {
DieCallback = callback;
InternalDieCallback = callback;
}
void SetUserDieCallback(DieCallbackType callback) {
UserDieCallback = callback;
}
DieCallbackType GetDieCallback() {
return DieCallback;
return InternalDieCallback;
}
void NORETURN Die() {
if (DieCallback) {
DieCallback();
}
if (UserDieCallback)
UserDieCallback();
if (InternalDieCallback)
InternalDieCallback();
internal__exit(1);
}
@ -280,4 +284,9 @@ void __sanitizer_set_report_path(const char *path) {
void __sanitizer_report_error_summary(const char *error_summary) {
Printf("%s\n", error_summary);
}
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_set_death_callback(void (*callback)(void)) {
SetUserDieCallback(callback);
}
} // extern "C"

View File

@ -245,6 +245,7 @@ bool SanitizerGetThreadName(char *name, int max_len);
// to do tool-specific job.
typedef void (*DieCallbackType)(void);
void SetDieCallback(DieCallbackType);
void SetUserDieCallback(DieCallbackType);
DieCallbackType GetDieCallback();
typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
u64, u64);

View File

@ -0,0 +1,49 @@
// RUN: %clangxx -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
// Check __sanitizer_set_death_callback. Not all sanitizers implement it yet.
// XFAIL: lsan
// XFAIL: tsan
#include <sanitizer/common_interface_defs.h>
#include <stdio.h>
#include <pthread.h>
volatile char *zero = 0;
void Death() {
fprintf(stderr, "DEATH CALLBACK EXECUTED\n");
}
// CHECK: DEATH CALLBACK EXECUTED
int global[10];
volatile char *sink;
void *Thread(void *x) {
global[0]++;
return x;
}
__attribute__((noinline))
void MaybeInit(int *uninitialized) {
if (zero)
*uninitialized = 1;
}
__attribute__((noinline))
void Leak() {
sink = new char[100]; // trigger lsan report.
}
int main(int argc, char **argv) {
int uninitialized;
__sanitizer_set_death_callback(Death);
MaybeInit(&uninitialized);
if (uninitialized) // trigger msan report.
global[0] = 77;
pthread_t t;
pthread_create(&t, 0, Thread, 0);
global[0]++; // trigger tsan report.
pthread_join(t, 0);
global[argc + 10]++; // trigger asan report.
Leak();
sink = 0;
}