[Sanitizer] Rework r176802: share code between Printf and Report and simplify it a bit
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@179755 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cc
index 9a0b71b..f1fb2b1 100644
--- a/lib/sanitizer_common/sanitizer_printf.cc
+++ b/lib/sanitizer_common/sanitizer_printf.cc
@@ -190,16 +190,66 @@
PrintfAndReportCallback(str);
}
-void Printf(const char *format, ...) {
+static void SharedPrintfCode(bool append_pid, const char *format,
+ va_list args) {
const int kLen = 16 * 1024;
- InternalScopedBuffer<char> buffer(kLen);
+ // |local_buffer| is small enough not to overflow the stack and/or violate
+ // the stack limit enforced by TSan (-Wframe-larger-than=512). On the other
+ // hand, the bigger the buffer is, the more the chance the error report will
+ // fit into it.
+ char local_buffer[400];
+ int needed_length;
+ char *buffer = local_buffer;
+ int buffer_size = ARRAY_SIZE(local_buffer);
+ // First try to print a message using a local buffer, and then fall back to
+ // mmaped buffer.
+ for (int use_mmap = 0; use_mmap < 2; use_mmap++) {
+ if (use_mmap) {
+ buffer = (char*)MmapOrDie(kLen, "Report");
+ buffer_size = kLen;
+ }
+ needed_length = 0;
+ if (append_pid) {
+ int pid = GetPid();
+ needed_length += internal_snprintf(buffer, buffer_size, "==%d==", pid);
+ if (needed_length >= buffer_size) {
+ // The pid doesn't fit into the current buffer.
+ if (!use_mmap)
+ continue;
+ RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
+ }
+ }
+ needed_length += VSNPrintf(buffer + needed_length,
+ buffer_size - needed_length, format, args);
+ if (needed_length >= buffer_size) {
+ // The message doesn't fit into the current buffer.
+ if (!use_mmap)
+ continue;
+ RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
+ }
+ // If the message fit into the buffer, print it and exit.
+ break;
+ }
+ RawWrite(buffer);
+ CallPrintfAndReportCallback(buffer);
+ // If we had mapped any memory, clean up.
+ if (buffer != local_buffer)
+ UnmapOrDie((void *)buffer, buffer_size);
+}
+
+void Printf(const char *format, ...) {
va_list args;
va_start(args, format);
- int needed_length = VSNPrintf(buffer.data(), kLen, format, args);
+ SharedPrintfCode(false, format, args);
va_end(args);
- RAW_CHECK_MSG(needed_length < kLen, "Buffer in Printf is too short!\n");
- RawWrite(buffer.data());
- CallPrintfAndReportCallback(buffer.data());
+}
+
+// Like Printf, but prints the current PID before the output string.
+void Report(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ SharedPrintfCode(true, format, args);
+ va_end(args);
}
// Writes at most "length" symbols to "buffer" (including trailing '\0').
@@ -214,54 +264,4 @@
return needed_length;
}
-// Like Printf, but prints the current PID before the output string.
-void Report(const char *format, ...) {
- const int kLen = 16 * 1024;
- // |local_buffer| is small enough not to overflow the stack and/or violate
- // the stack limit enforced by TSan (-Wframe-larger-than=512). On the other
- // hand, the bigger the buffer is, the more the chance the error report will
- // fit into it.
- char local_buffer[400];
- 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);
- CallPrintfAndReportCallback(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