summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_printf.cc
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-04-18 13:18:23 +0000
committerAlexey Samsonov <samsonov@google.com>2013-04-18 13:18:23 +0000
commit99f1e2011a855edd3b1036660ec5e7b70aa06520 (patch)
tree1be3c5a52f6ef5efb1de1cf983cb44e8d8b4a2b8 /lib/sanitizer_common/sanitizer_printf.cc
parente8a005f9aac3870f336b5949f7ff634e2b8a51da (diff)
[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
Diffstat (limited to 'lib/sanitizer_common/sanitizer_printf.cc')
-rw-r--r--lib/sanitizer_common/sanitizer_printf.cc110
1 files 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<char> 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