Index: lib/asan/asan_report.cc =================================================================== --- lib/asan/asan_report.cc +++ lib/asan/asan_report.cc @@ -23,6 +23,11 @@ #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_symbolizer.h" +#if SANITIZER_MAC +# include +# include +#endif + namespace __asan { // -------------------- User-specified callbacks ----------------- {{{1 @@ -45,16 +50,21 @@ static ReportData report_data = {}; void AppendToErrorMessageBuffer(const char *buffer) { - if (error_message_buffer) { - uptr length = internal_strlen(buffer); - CHECK_GE(error_message_buffer_size, error_message_buffer_pos); - uptr 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 += Min(remaining, length); + if (!error_message_buffer) { + error_message_buffer_size = 1 << 16; + error_message_buffer = + (char*)MmapOrDie(error_message_buffer_size, __func__); + error_message_buffer_pos = 0; } + + uptr length = internal_strlen(buffer); + CHECK_GE(error_message_buffer_size, error_message_buffer_pos); + uptr 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 += Min(remaining, length); } // ---------------------- Decorator ------------------------------ {{{1 @@ -617,6 +627,36 @@ // -------------------- Different kinds of reports ----------------- {{{1 +// Removes the ANSI escape sequences from the input string (in-place). +void RemoveANSIEscapeSequencesFromString(char *str) { + if (!str) + return; + + // We are going to remove the escape sequences in place. + char *s = str; + char *z = str; + while (*s != '\0') { + // Skip ANSI escape sequences. + if (*s == '\033' && *(s + 1) == '[') { + while (*s != 'm' && *s != '\0') { + s++; + } + if (*s == '\0') { + break; + } + // Copy over the buffer content. + } else if (s != z) { + CHECK_GT(s, z); + *z = *s; + z++; + } + s++; + } + + // Null terminate the string. + *z = '\0'; +} + // Use ScopedInErrorReport to run common actions just before and // immediately after printing error report. class ScopedInErrorReport { @@ -663,6 +703,20 @@ // Print memory stats. if (flags()->print_stats) __asan_print_accumulated_stats(); + +#if SANITIZER_MAC + RemoveANSIEscapeSequencesFromString(error_message_buffer); + + // Log the full message to syslog. + asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", error_message_buffer); + + // Log with os_trace. This will make it into the crash log. + if (&_os_trace_with_buffer != nullptr) { + os_trace("AddressSanitizer reported a failure. " + "Consult syslog for more information."); + } +#endif + if (error_report_callback) { error_report_callback(error_message_buffer); } @@ -1061,12 +1115,6 @@ void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) { error_report_callback = callback; - if (callback) { - error_message_buffer_size = 1 << 16; - error_message_buffer = - (char*)MmapOrDie(error_message_buffer_size, __func__); - error_message_buffer_pos = 0; - } } void __asan_describe_address(uptr addr) {