[compiler-rt] r176802 - [ASan] Try to use a small (512 bytes) stack-local buffer in Report() for short messages, fall back to MmapOrDie() in the case of a failure.

Alexander Potapenko glider at google.com
Mon Mar 11 04:47:43 PDT 2013


Author: glider
Date: Mon Mar 11 06:47:43 2013
New Revision: 176802

URL: http://llvm.org/viewvc/llvm-project?rev=176802&view=rev
Log:
[ASan] Try to use a small (512 bytes) stack-local buffer in Report() for short messages, fall back to MmapOrDie() in the case of a failure.
This shall eliminate most of the cryptic "ERROR: failed to mmap" messages caused by recursively calling MmapOrDie() from MmapOrDie().

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc?rev=176802&r1=176801&r2=176802&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc Mon Mar 11 06:47:43 2013
@@ -201,19 +201,48 @@ int internal_snprintf(char *buffer, uptr
 // Like Printf, but prints the current PID before the output string.
 void Report(const char *format, ...) {
   const int kLen = 16 * 1024;
-  InternalScopedBuffer<char> buffer(kLen);
-  int needed_length = internal_snprintf(buffer.data(),
-                                        kLen, "==%d== ", GetPid());
-  RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
-  va_list args;
-  va_start(args, format);
-  needed_length += VSNPrintf(buffer.data() + needed_length,
-                             kLen - needed_length, format, args);
-  va_end(args);
-  RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
-  RawWrite(buffer.data());
-  if (PrintfAndReportCallback)
-    PrintfAndReportCallback(buffer.data());
+  // |local_buffer| is small enough not to overflow the stack.
+  char local_buffer[512];
+  int needed_length;
+  int pid = GetPid();
+  char *buffer = local_buffer;
+  int cur_size = sizeof(local_buffer) / sizeof(char);
+  for (int use_mmap = 0; use_mmap < 2; use_mmap++) {
+    needed_length = internal_snprintf(buffer, cur_size,
+                                      "==%d==", pid);
+    if (needed_length >= cur_size) {
+      if (use_mmap) {
+        RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
+      } else {
+        // The pid doesn't fit into the local buffer.
+        continue;
+      }
+    }
+    va_list args;
+    va_start(args, format);
+    needed_length += VSNPrintf(buffer + needed_length,
+                               cur_size - needed_length, format, args);
+    va_end(args);
+    if (needed_length >= cur_size) {
+      if (use_mmap) {
+        RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
+      } else {
+        // The error message doesn't fit into the local buffer - allocate a bigger one.
+        buffer = (char*)MmapOrDie(kLen, "Report");
+        cur_size = kLen;
+        continue;
+      }
+    } else {
+      RawWrite(buffer);
+      if (PrintfAndReportCallback)
+        PrintfAndReportCallback(buffer);
+      // Don't do anything for the second time if the first iteration
+      // succeeded.
+      break;
+    }
+  }
+  // If we had mapped any memory, clean up.
+  if (buffer != local_buffer) UnmapOrDie((void*)buffer, cur_size);
 }
 
 }  // namespace __sanitizer





More information about the llvm-commits mailing list