[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