summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-08-13 11:23:40 +0000
committerAlexey Samsonov <samsonov@google.com>2012-08-13 11:23:40 +0000
commitf87ff74075693c7dd96a2ec1340cedc0fb8c3e11 (patch)
tree9b5bee415e5b0d57369ba19782c5353d43a6ec9c
parentbf4871d3635f67c4cd4cdea61dd0ff0d8f5d49ba (diff)
downloadbcm5719-llvm-f87ff74075693c7dd96a2ec1340cedc0fb8c3e11.tar.gz
bcm5719-llvm-f87ff74075693c7dd96a2ec1340cedc0fb8c3e11.zip
[ASan] Add __asan_set_on_error_callback() interface function that allows user to set a callback to be called right when ASan detects an error
llvm-svn: 161754
-rw-r--r--compiler-rt/lib/asan/asan_interface.h7
-rw-r--r--compiler-rt/lib/asan/asan_report.cc11
-rw-r--r--compiler-rt/lib/asan/tests/asan_noinst_test.cc6
3 files changed, 23 insertions, 1 deletions
diff --git a/compiler-rt/lib/asan/asan_interface.h b/compiler-rt/lib/asan/asan_interface.h
index c625a6217c0..c1390ceb8af 100644
--- a/compiler-rt/lib/asan/asan_interface.h
+++ b/compiler-rt/lib/asan/asan_interface.h
@@ -118,6 +118,13 @@ extern "C" {
void __asan_set_error_report_callback(void (*callback)(const char*))
SANITIZER_INTERFACE_ATTRIBUTE;
+ // Sets the callback to be called right when ASan detects an error.
+ // This can be used to notice cases when ASan detects an error, but the
+ // program crashes before ASan report is printed.
+ // Passing 0 unsets the callback.
+ void __asan_set_on_error_callback(void (*callback)(void))
+ SANITIZER_INTERFACE_ATTRIBUTE;
+
// Returns the estimated number of bytes that will be reserved by allocator
// for request of "size" bytes. If ASan allocator can't allocate that much
// memory, returns the maximal possible allocation size, otherwise returns
diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc
index 883b84b26a2..1cabbcdd91c 100644
--- a/compiler-rt/lib/asan/asan_report.cc
+++ b/compiler-rt/lib/asan/asan_report.cc
@@ -21,7 +21,7 @@
namespace __asan {
-// ---------------------- Error report callback ------------------- {{{1
+// -------------------- User-specified callbacks ----------------- {{{1
static void (*error_report_callback)(const char*);
static char *error_message_buffer = 0;
static uptr error_message_buffer_pos = 0;
@@ -40,6 +40,8 @@ void AppendToErrorMessageBuffer(const char *buffer) {
}
}
+static void (*on_error_callback)(void);
+
// ---------------------- Helper functions ----------------------- {{{1
static void PrintBytes(const char *before, uptr *a) {
@@ -219,6 +221,9 @@ class ScopedInErrorReport {
SleepForSeconds(Max(5, flags()->sleep_before_dying + 1));
Die();
}
+ if (on_error_callback) {
+ on_error_callback();
+ }
AsanPrintf("===================================================="
"=============\n");
AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
@@ -409,3 +414,7 @@ void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
error_message_buffer_pos = 0;
}
}
+
+void NOINLINE __asan_set_on_error_callback(void (*callback)(void)) {
+ on_error_callback = callback;
+}
diff --git a/compiler-rt/lib/asan/tests/asan_noinst_test.cc b/compiler-rt/lib/asan/tests/asan_noinst_test.cc
index 44d4c3c845b..e066d0be3a2 100644
--- a/compiler-rt/lib/asan/tests/asan_noinst_test.cc
+++ b/compiler-rt/lib/asan/tests/asan_noinst_test.cc
@@ -530,6 +530,12 @@ TEST(AddressSanitizerInterface, DeathCallbackTest) {
__asan_set_death_callback(NULL);
}
+TEST(AddressSanitizerInterface, OnErrorCallbackTest) {
+ __asan_set_on_error_callback(MyDeathCallback);
+ EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback.*double-free");
+ __asan_set_on_error_callback(NULL);
+}
+
static const char* kUseAfterPoisonErrorMessage = "use-after-poison";
#define GOOD_ACCESS(ptr, offset) \
OpenPOWER on IntegriCloud