Index: lib/asan/asan_report.cc =================================================================== --- lib/asan/asan_report.cc +++ lib/asan/asan_report.cc @@ -55,7 +55,7 @@ error_message_buffer_pos = 0; } uptr length = internal_strlen(buffer); - CHECK_GE(error_message_buffer_size, error_message_buffer_pos); + RAW_CHECK(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); @@ -670,13 +670,22 @@ // Print memory stats. if (flags()->print_stats) __asan_print_accumulated_stats(); + + // Copy the message buffer so that we could start logging without holding a + // lock that gets aquired during printing. + char *error_message_buffer_copy = nullptr; { BlockingMutexLock l(&error_message_buf_mutex); - LogFullErrorReport(error_message_buffer); + error_message_buffer_copy = internal_strdup(error_message_buffer); + } - if (error_report_callback) { - error_report_callback(error_message_buffer); - } + // Remove color sequences since logs cannot print them. + RemoveANSIEscapeSequencesFromString(error_message_buffer_copy); + + LogFullErrorReport(error_message_buffer_copy); + + if (error_report_callback) { + error_report_callback(error_message_buffer_copy); } Report("ABORTING\n"); Die(); Index: lib/sanitizer_common/sanitizer_common.h =================================================================== --- lib/sanitizer_common/sanitizer_common.h +++ lib/sanitizer_common/sanitizer_common.h @@ -76,7 +76,10 @@ uptr *tls_addr, uptr *tls_size); // Memory management -void *MmapOrDie(uptr size, const char *mem_type); +void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false); +INLINE void *MmapOrDieQuietly(uptr size, const char *mem_type) { + return MmapOrDie(size, mem_type, /*raw_report*/ true); +} void UnmapOrDie(void *addr, uptr size); void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name = nullptr); @@ -311,6 +314,7 @@ CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2); void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, const char *mmap_type, error_t err); +void NORETURN RawReportMmapFailureAndDie(); // Set the name of the current thread to 'name', return true on succees. // The name may be truncated to a system-dependent limit. @@ -423,7 +427,7 @@ } INLINE uptr RoundUpTo(uptr size, uptr boundary) { - CHECK(IsPowerOfTwo(boundary)); + RAW_CHECK(IsPowerOfTwo(boundary)); return (size + boundary - 1) & ~(boundary - 1); } Index: lib/sanitizer_common/sanitizer_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_common.cc +++ lib/sanitizer_common/sanitizer_common.cc @@ -163,14 +163,18 @@ Die(); } +void NORETURN RawReportMmapFailureAndDie() { + RawWrite("ERROR: Failed to mmap\n"); + Die(); +} + void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, const char *mmap_type, error_t err) { static int recursion_count; if (recursion_count) { // The Report() and CHECK calls below may call mmap recursively and fail. // If we went into recursion, just die. - RawWrite("ERROR: Failed to mmap\n"); - Die(); + RawReportMmapFailureAndDie(); } recursion_count++; Report("ERROR: %s failed to " Index: lib/sanitizer_common/sanitizer_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_mac.cc +++ lib/sanitizer_common/sanitizer_mac.cc @@ -381,6 +381,9 @@ } void LogFullErrorReport(const char *buffer) { + if (!buffer) + return; + // Log with os_trace. This will make it into the crash log. if (GetMacosVersion() >= MACOS_VERSION_MAVERICKS) { // os_trace requires the message (format parameter) to be a string literal. Index: lib/sanitizer_common/sanitizer_posix.cc =================================================================== --- lib/sanitizer_common/sanitizer_posix.cc +++ lib/sanitizer_common/sanitizer_posix.cc @@ -112,14 +112,18 @@ #endif // SANITIZER_WORDSIZE } -void *MmapOrDie(uptr size, const char *mem_type) { +void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { size = RoundUpTo(size, GetPageSizeCached()); uptr res = internal_mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); int reserrno; - if (internal_iserror(res, &reserrno)) - ReportMmapFailureAndDie(size, mem_type, "allocate", reserrno); + if (internal_iserror(res, &reserrno)) { + if (raw_report) + RawReportMmapFailureAndDie(); + else + ReportMmapFailureAndDie(size, mem_type, "allocate", reserrno); + } IncreaseTotalMmap(size); return (void *)res; } Index: lib/sanitizer_common/sanitizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_win.cc +++ lib/sanitizer_common/sanitizer_win.cc @@ -83,10 +83,14 @@ } #endif // #if !SANITIZER_GO -void *MmapOrDie(uptr size, const char *mem_type) { +void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (rv == 0) - ReportMmapFailureAndDie(size, mem_type, "allocate", GetLastError()); + if (rv == 0) { + if (raw_report) + RawReportMmapFailureAndDie(); + else + ReportMmapFailureAndDie(size, mem_type, "allocate", GetLastError()); + } return rv; }