diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp --- a/compiler-rt/lib/ubsan/ubsan_diag.cpp +++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp @@ -388,6 +388,10 @@ ScopedReport::~ScopedReport() { MaybePrintStackTrace(Opts.pc, Opts.bp); MaybeReportErrorSummary(SummaryLoc, Type); + + if (common_flags()->print_module_map >= 2) + DumpProcessMap(); + if (flags()->halt_on_error) Die(); } diff --git a/compiler-rt/lib/ubsan/ubsan_init.cpp b/compiler-rt/lib/ubsan/ubsan_init.cpp --- a/compiler-rt/lib/ubsan/ubsan_init.cpp +++ b/compiler-rt/lib/ubsan/ubsan_init.cpp @@ -33,6 +33,11 @@ InitializeSuppressions(); } +static void UbsanDie() { + if (common_flags()->print_module_map >= 1) + DumpProcessMap(); +} + static void CommonStandaloneInit() { SanitizerToolName = GetSanititizerToolName(); CacheBinaryName(); @@ -42,6 +47,10 @@ AndroidLogInit(); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); CommonInit(); + + // Only add die callback when running in standalone mode to avoid printing + // the same information from multiple sanitizers' output + AddDieCallback(UbsanDie); Symbolizer::LateInitialize(); } diff --git a/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-module-map.cpp b/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-module-map.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-module-map.cpp @@ -0,0 +1,35 @@ +// Checks that module map does not print at 0, prints once after aborting with 1, +// and prints once before and after aborting with 2 + +// RUN: %clangxx -DUSING_%tool_name %s -o %t + +// RUN: %env_tool_opts="print_module_map=0" not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-MM0 +// RUN: %env_tool_opts="print_module_map=1" not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-MM1 +// RUN: %env_tool_opts="print_module_map=2" not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-MM2 + +// UNSUPPORTED: lsan +// tsan support pending rdar://67747473 +// UNSUPPORTED: tsan + +int global; + +int main() { +#if defined(USING_ubsan) + int value = 5; + int computation = value / 0; // Division by zero. +#else + volatile int *a = new int[100]; + delete[] a; + global = a[0]; // use-after-free: triggers ASan/TSan report. +#endif + return 0; +} + +// CHECK: SUMMARY: +// CHECK-MM0-NOT: Process module map: +// CHECK-MM1-NOT: Process module map: +// CHECK-MM2: Process module map: +// CHECK: ABORTING +// CHECK-MM0-NOT: Process module map: +// CHECK-MM1-NEXT: Process module map: +// CHECK-MM2-NEXT: Process module map: