[ASan] Change __asan_set_on_error_callback to weak overridable __asan_on_error, so that ASan would call the latter even if it finds the error early (i.e. during module initialization)
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@165008 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/sanitizer/asan_interface.h b/include/sanitizer/asan_interface.h
index 787e811..788e90f 100644
--- a/include/sanitizer/asan_interface.h
+++ b/include/sanitizer/asan_interface.h
@@ -128,12 +128,11 @@
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;
+ // User may provide function that would 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.
+ void __asan_on_error()
+ SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE;
// User may provide its own implementation for symbolization function.
// It should print the description of instruction at address "pc" to
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 5baba45..4b7baa6 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -40,8 +40,6 @@
}
}
-static void (*on_error_callback)(void);
-
// ---------------------- Helper functions ----------------------- {{{1
static void PrintBytes(const char *before, uptr *a) {
@@ -293,9 +291,7 @@
}
Die();
}
- if (on_error_callback) {
- on_error_callback();
- }
+ __asan_on_error();
reporting_thread_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
Printf("===================================================="
"=============\n");
@@ -492,6 +488,7 @@
}
}
-void NOINLINE __asan_set_on_error_callback(void (*callback)(void)) {
- on_error_callback = callback;
-}
+// Provide default implementation of __asan_on_error that does nothing
+// and may be overriden by user.
+SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE NOINLINE
+void __asan_on_error() {}
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index c7aedb2..14667e6 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -241,7 +241,7 @@
case 27: __asan_set_error_exit_code(0); break;
case 28: __asan_stack_free(0, 0, 0); break;
case 29: __asan_stack_malloc(0, 0); break;
- case 30: __asan_set_on_error_callback(0); break;
+ case 30: __asan_on_error(); break;
case 31: __asan_default_options(); break;
case 32: __asan_before_dynamic_init(0, 0); break;
case 33: __asan_after_dynamic_init(); break;
diff --git a/lib/asan/lit_tests/on_error_callback.cc b/lib/asan/lit_tests/on_error_callback.cc
new file mode 100644
index 0000000..bb94d9f
--- /dev/null
+++ b/lib/asan/lit_tests/on_error_callback.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C"
+void __asan_on_error() {
+ fprintf(stderr, "__asan_on_error called");
+}
+
+int main() {
+ char *x = (char*)malloc(10 * sizeof(char));
+ free(x);
+ return x[5];
+ // CHECK: __asan_on_error called
+}
diff --git a/lib/asan/tests/asan_noinst_test.cc b/lib/asan/tests/asan_noinst_test.cc
index 037af9e..5b286b7 100644
--- a/lib/asan/tests/asan_noinst_test.cc
+++ b/lib/asan/tests/asan_noinst_test.cc
@@ -530,12 +530,6 @@
__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) \