From 99f1e2011a855edd3b1036660ec5e7b70aa06520 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Thu, 18 Apr 2013 13:18:23 +0000 Subject: [PATCH] [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 --- lib/sanitizer_common/sanitizer_printf.cc | 110 +++++++++++++++---------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cc index 9a0b71b91..f1fb2b1fe 100644 --- a/lib/sanitizer_common/sanitizer_printf.cc +++ b/lib/sanitizer_common/sanitizer_printf.cc @@ -190,32 +190,8 @@ static void CallPrintfAndReportCallback(const char *str) { PrintfAndReportCallback(str); } -void Printf(const char *format, ...) { - const int kLen = 16 * 1024; - InternalScopedBuffer buffer(kLen); - va_list args; - va_start(args, format); - int needed_length = VSNPrintf(buffer.data(), kLen, format, args); - va_end(args); - RAW_CHECK_MSG(needed_length < kLen, "Buffer in Printf is too short!\n"); - RawWrite(buffer.data()); - CallPrintfAndReportCallback(buffer.data()); -} - -// Writes at most "length" symbols to "buffer" (including trailing '\0'). -// Returns the number of symbols that should have been written to buffer -// (not including trailing '\0'). Thus, the string is truncated -// iff return value is not less than "length". -int internal_snprintf(char *buffer, uptr length, const char *format, ...) { - va_list args; - va_start(args, format); - int needed_length = VSNPrintf(buffer, length, format, args); - va_end(args); - return needed_length; -} - -// Like Printf, but prints the current PID before the output string. -void Report(const char *format, ...) { +static void SharedPrintfCode(bool append_pid, const char *format, + va_list args) { 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 @@ -223,45 +199,69 @@ void Report(const char *format, ...) { // 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); + 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++) { - needed_length = internal_snprintf(buffer, cur_size, - "==%d==", pid); - if (needed_length >= cur_size) { - if (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"); - } 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; + buffer_size - needed_length, format, args); + if (needed_length >= buffer_size) { + // The message doesn't fit into the current buffer. + if (!use_mmap) continue; - } - } else { - RawWrite(buffer); - CallPrintfAndReportCallback(buffer); - // Don't do anything for the second time if the first iteration - // succeeded. - break; + 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, cur_size); + if (buffer != local_buffer) + UnmapOrDie((void *)buffer, buffer_size); +} + +void Printf(const char *format, ...) { + va_list args; + va_start(args, format); + SharedPrintfCode(false, format, args); + va_end(args); +} + +// 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'). +// Returns the number of symbols that should have been written to buffer +// (not including trailing '\0'). Thus, the string is truncated +// iff return value is not less than "length". +int internal_snprintf(char *buffer, uptr length, const char *format, ...) { + va_list args; + va_start(args, format); + int needed_length = VSNPrintf(buffer, length, format, args); + va_end(args); + return needed_length; } } // namespace __sanitizer -- 2.11.4.GIT