[llvm-commits] [compiler-rt] r151528 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_interceptors.h asan_interface.h asan_printf.cc asan_rtl.cc tests/asan_interface_test.cc
Alexander Potapenko
glider at google.com
Mon Feb 27 06:06:48 PST 2012
Author: glider
Date: Mon Feb 27 08:06:48 2012
New Revision: 151528
URL: http://llvm.org/viewvc/llvm-project?rev=151528&view=rev
Log:
Introduce __asan_set_error_report_callback() to allow the client program post-process the error reports.
If the callback is set, Report() and Printf() print the reports into a buffer (together with stderr), which is then passed to the client.
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/asan_interceptors.h
compiler-rt/trunk/lib/asan/asan_interface.h
compiler-rt/trunk/lib/asan/asan_printf.cc
compiler-rt/trunk/lib/asan/asan_rtl.cc
compiler-rt/trunk/lib/asan/tests/asan_interface_test.cc
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=151528&r1=151527&r2=151528&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Feb 27 08:06:48 2012
@@ -222,6 +222,13 @@
return 0;
}
+char *internal_strncpy(char *dst, const char *src, size_t n) {
+ size_t i;
+ for (i = 0; i < n && src[i]; i++)
+ dst[i] = src[i];
+ return dst;
+}
+
} // namespace __asan
// ---------------------- Wrappers ---------------- {{{1
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=151528&r1=151527&r2=151528&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Mon Feb 27 08:06:48 2012
@@ -40,6 +40,7 @@
char *internal_strstr(const char *haystack, const char *needle);
char *internal_strncat(char *dst, const char *src, size_t n);
int internal_strcmp(const char *s1, const char *s2);
+char *internal_strncpy(char *dst, const char *src, size_t n);
// Works only for base=10 and doesn't set errno.
int64_t internal_simple_strtoll(const char *nptr, char **endptr, int base);
Modified: compiler-rt/trunk/lib/asan/asan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interface.h?rev=151528&r1=151527&r2=151528&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interface.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interface.h Mon Feb 27 08:06:48 2012
@@ -121,6 +121,9 @@
void __asan_set_death_callback(void (*callback)(void))
ASAN_INTERFACE_FUNCTION_ATTRIBUTE;
+ void __asan_set_error_report_callback(void (*callback)(const char*))
+ ASAN_INTERFACE_FUNCTION_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
Modified: compiler-rt/trunk/lib/asan/asan_printf.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_printf.cc?rev=151528&r1=151527&r2=151528&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_printf.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_printf.cc Mon Feb 27 08:06:48 2012
@@ -22,6 +22,9 @@
namespace __asan {
+extern char *error_message_buffer;
+extern size_t error_message_buffer_pos, error_message_buffer_size;
+
void RawWrite(const char *buffer) {
static const char *kRawWriteError = "RawWrite can't output requested buffer!";
size_t length = (size_t)internal_strlen(buffer);
@@ -29,6 +32,14 @@
AsanWrite(2, kRawWriteError, internal_strlen(kRawWriteError));
AsanDie();
}
+ if (error_message_buffer) {
+ int remaining = error_message_buffer_size - error_message_buffer_pos;
+ internal_strncpy(error_message_buffer + error_message_buffer_pos,
+ buffer, remaining);
+ error_message_buffer[error_message_buffer_size - 1] = '\0';
+ // FIXME: reallocate the buffer instead of truncating the message.
+ error_message_buffer_pos += remaining > length ? length : remaining;
+ }
}
static inline int AppendChar(char **buff, const char *buff_end, char c) {
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=151528&r1=151527&r2=151528&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Mon Feb 27 08:06:48 2012
@@ -52,6 +52,10 @@
int asan_inited;
bool asan_init_is_running;
static void (*death_callback)(void);
+static void (*error_report_callback)(const char*);
+char *error_message_buffer = NULL;
+size_t error_message_buffer_pos = 0;
+size_t error_message_buffer_size = 0;
// -------------------------- Misc ---------------- {{{1
void ShowStatsAndAbort() {
@@ -237,7 +241,7 @@
// dynamic libraries access the symbol even if it is not used by the executable
// itself. This should help if the build system is removing dead code at link
// time.
-static void force_interface_symbols() {
+static NOINLINE void force_interface_symbols() {
volatile int fake_condition = 0; // prevent dead condition elimination.
if (fake_condition) {
__asan_report_load1(NULL);
@@ -253,6 +257,7 @@
__asan_register_global(0, 0, NULL);
__asan_register_globals(NULL, 0);
__asan_unregister_globals(NULL, 0);
+ __asan_set_error_report_callback(NULL);
}
}
@@ -300,6 +305,16 @@
death_callback = callback;
}
+void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
+ error_report_callback = callback;
+ if (callback) {
+ error_message_buffer_size = 1 << 14;
+ error_message_buffer =
+ (char*)AsanMmapSomewhereOrDie(error_message_buffer_size, __FUNCTION__);
+ error_message_buffer_pos = 0;
+ }
+}
+
void __asan_report_error(uintptr_t pc, uintptr_t bp, uintptr_t sp,
uintptr_t addr, bool is_write, size_t access_size) {
// Do not print more than one report, otherwise they will mix up.
@@ -389,6 +404,9 @@
PrintBytes(" ", (uintptr_t*)(aligned_shadow+2*kWordSize));
PrintBytes(" ", (uintptr_t*)(aligned_shadow+3*kWordSize));
PrintBytes(" ", (uintptr_t*)(aligned_shadow+4*kWordSize));
+ if (error_report_callback) {
+ error_report_callback(error_message_buffer);
+ }
AsanDie();
}
Modified: compiler-rt/trunk/lib/asan/tests/asan_interface_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_interface_test.cc?rev=151528&r1=151527&r2=151528&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_interface_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_interface_test.cc Mon Feb 27 08:06:48 2012
@@ -342,3 +342,21 @@
kInvalidPoisonMessage);
free(array);
}
+
+static void ErrorReportCallbackOneToZ(const char *report) {
+ int len = strlen(report);
+ char *dup = (char*)malloc(len);
+ strcpy(dup, report);
+ for (int i = 0; i < len; i++) {
+ if (dup[i] == '1') dup[i] = 'Z';
+ }
+ write(2, dup, len);
+ free(dup);
+}
+
+TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
+ __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
+ char *array = Ident((char*)malloc(120));
+ EXPECT_DEATH(ACCESS(array, 120), "size Z");
+ __asan_set_error_report_callback(NULL);
+}
More information about the llvm-commits
mailing list