summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/CMakeLists.txt2
-rw-r--r--lib/asan/tests/CMakeLists.txt3
-rw-r--r--lib/esan/CMakeLists.txt1
-rw-r--r--lib/hwasan/CMakeLists.txt2
-rw-r--r--lib/lsan/CMakeLists.txt2
-rw-r--r--lib/msan/CMakeLists.txt1
-rw-r--r--lib/sanitizer_common/CMakeLists.txt37
-rw-r--r--lib/sanitizer_common/sanitizer_common.cc14
-rw-r--r--lib/sanitizer_common/sanitizer_common_libcdep.cc250
-rw-r--r--lib/sanitizer_common/sanitizer_coverage_fuchsia.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_fuchsia.cc48
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_fuchsia.cc45
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_report.cc282
-rw-r--r--lib/sanitizer_common/tests/CMakeLists.txt9
-rw-r--r--lib/scudo/CMakeLists.txt7
-rw-r--r--lib/tsan/CMakeLists.txt2
-rwxr-xr-xlib/tsan/go/buildgo.sh1
-rw-r--r--lib/tsan/tests/CMakeLists.txt1
-rw-r--r--lib/ubsan/CMakeLists.txt4
23 files changed, 386 insertions, 336 deletions
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
index 31747adfc..a95d3ce08 100644
--- a/lib/asan/CMakeLists.txt
+++ b/lib/asan/CMakeLists.txt
@@ -126,6 +126,7 @@ if(APPLE)
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTLSanCommon
RTUbsan
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
@@ -140,6 +141,7 @@ else()
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTLSanCommon
RTUbsan)
diff --git a/lib/asan/tests/CMakeLists.txt b/lib/asan/tests/CMakeLists.txt
index 3b1ceddc1..1b7060591 100644
--- a/lib/asan/tests/CMakeLists.txt
+++ b/lib/asan/tests/CMakeLists.txt
@@ -252,6 +252,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
$<TARGET_OBJECTS:RTSanitizerCommon.osx>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>
$<TARGET_OBJECTS:RTLSanCommon.osx>
$<TARGET_OBJECTS:RTUbsan.osx>)
else()
@@ -262,6 +263,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
@@ -286,6 +288,7 @@ if(ANDROID)
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
${COMPILER_RT_GTEST_SOURCE}
diff --git a/lib/esan/CMakeLists.txt b/lib/esan/CMakeLists.txt
index 2012ab642..2349fe2ff 100644
--- a/lib/esan/CMakeLists.txt
+++ b/lib/esan/CMakeLists.txt
@@ -26,6 +26,7 @@ foreach (arch ${ESAN_SUPPORTED_ARCH})
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
CFLAGS ${ESAN_RTL_CFLAGS})
add_sanitizer_rt_symbols(clang_rt.esan
ARCHS ${arch}
diff --git a/lib/hwasan/CMakeLists.txt b/lib/hwasan/CMakeLists.txt
index 34f5f15b9..88a1e8c53 100644
--- a/lib/hwasan/CMakeLists.txt
+++ b/lib/hwasan/CMakeLists.txt
@@ -79,6 +79,7 @@ foreach(arch ${HWASAN_SUPPORTED_ARCH})
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTUbsan
CFLAGS ${HWASAN_RTL_CFLAGS}
PARENT_TARGET hwasan)
@@ -114,6 +115,7 @@ foreach(arch ${HWASAN_SUPPORTED_ARCH})
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTUbsan
# The only purpose of RTHWAsan_dynamic_version_script_dummy is to
# carry a dependency of the shared runtime on the version script.
diff --git a/lib/lsan/CMakeLists.txt b/lib/lsan/CMakeLists.txt
index 86b2bc1e3..c1700dd06 100644
--- a/lib/lsan/CMakeLists.txt
+++ b/lib/lsan/CMakeLists.txt
@@ -44,6 +44,7 @@ if(COMPILER_RT_HAS_LSAN)
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
CFLAGS ${LSAN_CFLAGS}
LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
LINK_LIBS ${LSAN_LINK_LIBS}
@@ -58,6 +59,7 @@ if(COMPILER_RT_HAS_LSAN)
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
CFLAGS ${LSAN_CFLAGS}
PARENT_TARGET lsan)
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt
index ebe0b64d1..fa8d8e1a0 100644
--- a/lib/msan/CMakeLists.txt
+++ b/lib/msan/CMakeLists.txt
@@ -41,6 +41,7 @@ foreach(arch ${MSAN_SUPPORTED_ARCH})
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
CFLAGS ${MSAN_RTL_CFLAGS}
PARENT_TARGET msan)
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
index 25255889f..e37fe1b18 100644
--- a/lib/sanitizer_common/CMakeLists.txt
+++ b/lib/sanitizer_common/CMakeLists.txt
@@ -31,16 +31,8 @@ set(SANITIZER_SOURCES_NOTERMINATION
sanitizer_procmaps_mac.cc
sanitizer_procmaps_solaris.cc
sanitizer_solaris.cc
- sanitizer_stackdepot.cc
- sanitizer_stacktrace.cc
- sanitizer_stacktrace_printer.cc
sanitizer_stoptheworld_mac.cc
sanitizer_suppressions.cc
- sanitizer_symbolizer.cc
- sanitizer_symbolizer_fuchsia.cc
- sanitizer_symbolizer_libbacktrace.cc
- sanitizer_symbolizer_mac.cc
- sanitizer_symbolizer_win.cc
sanitizer_tls_get_addr.cc
sanitizer_thread_registry.cc
sanitizer_win.cc)
@@ -67,12 +59,7 @@ set(SANITIZER_LIBCDEP_SOURCES
sanitizer_linux_libcdep.cc
sanitizer_mac_libcdep.cc
sanitizer_posix_libcdep.cc
- sanitizer_stacktrace_libcdep.cc
- sanitizer_stoptheworld_linux_libcdep.cc
- sanitizer_symbolizer_libcdep.cc
- sanitizer_symbolizer_posix_libcdep.cc
- sanitizer_unwind_linux_libcdep.cc
- sanitizer_unwind_win.cc)
+ sanitizer_stoptheworld_linux_libcdep.cc)
set(SANITIZER_COVERAGE_SOURCES
sancov_flags.cc
@@ -80,6 +67,22 @@ set(SANITIZER_COVERAGE_SOURCES
sanitizer_coverage_libcdep_new.cc
sanitizer_coverage_win_sections.cc)
+set(SANITIZER_SYMBOLIZER_SOURCES
+ sanitizer_stackdepot.cc
+ sanitizer_stacktrace.cc
+ sanitizer_stacktrace_libcdep.cc
+ sanitizer_stacktrace_printer.cc
+ sanitizer_symbolizer.cc
+ sanitizer_symbolizer_fuchsia.cc
+ sanitizer_symbolizer_libbacktrace.cc
+ sanitizer_symbolizer_libcdep.cc
+ sanitizer_symbolizer_mac.cc
+ sanitizer_symbolizer_posix_libcdep.cc
+ sanitizer_symbolizer_report.cc
+ sanitizer_symbolizer_win.cc
+ sanitizer_unwind_linux_libcdep.cc
+ sanitizer_unwind_win.cc)
+
# Explicitly list all sanitizer_common headers. Not all of these are
# included in sanitizer_common source files, but we need to depend on
# headers when building our custom unit tests.
@@ -217,6 +220,12 @@ add_compiler_rt_object_libraries(RTSanitizerCommonCoverage
SOURCES ${SANITIZER_COVERAGE_SOURCES}
CFLAGS ${SANITIZER_CFLAGS}
DEFS ${SANITIZER_COMMON_DEFINITIONS})
+add_compiler_rt_object_libraries(RTSanitizerCommonSymbolizer
+ ${OS_OPTION}
+ ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+ SOURCES ${SANITIZER_SYMBOLIZER_SOURCES}
+ CFLAGS ${SANITIZER_CFLAGS}
+ DEFS ${SANITIZER_COMMON_DEFINITIONS})
set(SANITIZER_NO_WEAK_HOOKS_CFLAGS ${SANITIZER_CFLAGS})
list(APPEND SANITIZER_NO_WEAK_HOOKS_CFLAGS "-DSANITIZER_SUPPORTS_WEAK_HOOKS=0")
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc
index ae26d5efc..04e3dd7f7 100644
--- a/lib/sanitizer_common/sanitizer_common.cc
+++ b/lib/sanitizer_common/sanitizer_common.cc
@@ -17,8 +17,6 @@
#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
#include "sanitizer_placement_new.h"
-#include "sanitizer_stacktrace_printer.h"
-#include "sanitizer_symbolizer.h"
namespace __sanitizer {
@@ -107,18 +105,6 @@ void ReportErrorSummary(const char *error_message, const char *alt_tool_name) {
__sanitizer_report_error_summary(buff.data());
}
-#if !SANITIZER_GO
-void ReportErrorSummary(const char *error_type, const AddressInfo &info,
- const char *alt_tool_name) {
- if (!common_flags()->print_summary) return;
- InternalScopedString buff(kMaxSummaryLength);
- buff.append("%s ", error_type);
- RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style,
- common_flags()->strip_path_prefix);
- ReportErrorSummary(buff.data(), alt_tool_name);
-}
-#endif
-
// Removes the ANSI escape sequences from the input string (in-place).
void RemoveANSIEscapeSequencesFromString(char *str) {
if (!str)
diff --git a/lib/sanitizer_common/sanitizer_common_libcdep.cc b/lib/sanitizer_common/sanitizer_common_libcdep.cc
index 5e56e31fe..796a05485 100644
--- a/lib/sanitizer_common/sanitizer_common_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_common_libcdep.cc
@@ -11,100 +11,14 @@
// run-time libraries.
//===----------------------------------------------------------------------===//
-#include "sanitizer_common.h"
-
#include "sanitizer_allocator_interface.h"
-#include "sanitizer_file.h"
+#include "sanitizer_common.h"
#include "sanitizer_flags.h"
#include "sanitizer_procmaps.h"
-#include "sanitizer_report_decorator.h"
-#include "sanitizer_stacktrace.h"
-#include "sanitizer_symbolizer.h"
-#if SANITIZER_POSIX
-#include "sanitizer_posix.h"
-#include <sys/mman.h>
-#endif
namespace __sanitizer {
-#if !SANITIZER_FUCHSIA
-
-bool ReportFile::SupportsColors() {
- SpinMutexLock l(mu);
- ReopenIfNecessary();
- return SupportsColoredOutput(fd);
-}
-
-static INLINE bool ReportSupportsColors() {
- return report_file.SupportsColors();
-}
-
-#else // SANITIZER_FUCHSIA
-
-// Fuchsia's logs always go through post-processing that handles colorization.
-static INLINE bool ReportSupportsColors() { return true; }
-
-#endif // !SANITIZER_FUCHSIA
-
-bool ColorizeReports() {
- // FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color
- // printing on Windows.
- if (SANITIZER_WINDOWS)
- return false;
-
- const char *flag = common_flags()->color;
- return internal_strcmp(flag, "always") == 0 ||
- (internal_strcmp(flag, "auto") == 0 && ReportSupportsColors());
-}
-
-void ReportErrorSummary(const char *error_type, const StackTrace *stack,
- const char *alt_tool_name) {
-#if !SANITIZER_GO
- if (!common_flags()->print_summary)
- return;
- if (stack->size == 0) {
- ReportErrorSummary(error_type);
- return;
- }
- // Currently, we include the first stack frame into the report summary.
- // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc).
- uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
- SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
- ReportErrorSummary(error_type, frame->info, alt_tool_name);
- frame->ClearAll();
-#endif
-}
-
-void ReportMmapWriteExec(int prot) {
-#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID)
- if ((prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC))
- return;
-
- ScopedErrorReportLock l;
- SanitizerCommonDecorator d;
-
- InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
- BufferedStackTrace *stack = stack_buffer.data();
- stack->Reset();
- uptr top = 0;
- uptr bottom = 0;
- GET_CALLER_PC_BP_SP;
- (void)sp;
- bool fast = common_flags()->fast_unwind_on_fatal;
- if (fast)
- GetThreadStackTopAndBottom(false, &top, &bottom);
- stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, fast);
-
- Printf("%s", d.Warning());
- Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName);
- Printf("%s", d.Default());
-
- stack->Print();
- ReportErrorSummary("w-and-x-usage", stack);
-#endif
-}
-
static void (*SoftRssLimitExceededCallback)(bool exceeded);
void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) {
CHECK_EQ(SoftRssLimitExceededCallback, nullptr);
@@ -178,127 +92,6 @@ void BackgroundThread(void *arg) {
}
#endif
-#if !SANITIZER_FUCHSIA && !SANITIZER_GO
-void StartReportDeadlySignal() {
- // Write the first message using fd=2, just in case.
- // It may actually fail to write in case stderr is closed.
- CatastrophicErrorWrite(SanitizerToolName, internal_strlen(SanitizerToolName));
- static const char kDeadlySignal[] = ":DEADLYSIGNAL\n";
- CatastrophicErrorWrite(kDeadlySignal, sizeof(kDeadlySignal) - 1);
-}
-
-static void MaybeReportNonExecRegion(uptr pc) {
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
- MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
- MemoryMappedSegment segment;
- while (proc_maps.Next(&segment)) {
- if (pc >= segment.start && pc < segment.end && !segment.IsExecutable())
- Report("Hint: PC is at a non-executable region. Maybe a wild jump?\n");
- }
-#endif
-}
-
-static void PrintMemoryByte(InternalScopedString *str, const char *before,
- u8 byte) {
- SanitizerCommonDecorator d;
- str->append("%s%s%x%x%s ", before, d.MemoryByte(), byte >> 4, byte & 15,
- d.Default());
-}
-
-static void MaybeDumpInstructionBytes(uptr pc) {
- if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
- return;
- InternalScopedString str(1024);
- str.append("First 16 instruction bytes at pc: ");
- if (IsAccessibleMemoryRange(pc, 16)) {
- for (int i = 0; i < 16; ++i) {
- PrintMemoryByte(&str, "", ((u8 *)pc)[i]);
- }
- str.append("\n");
- } else {
- str.append("unaccessible\n");
- }
- Report("%s", str.data());
-}
-
-static void MaybeDumpRegisters(void *context) {
- if (!common_flags()->dump_registers) return;
- SignalContext::DumpAllRegisters(context);
-}
-
-static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid,
- UnwindSignalStackCallbackType unwind,
- const void *unwind_context) {
- SanitizerCommonDecorator d;
- Printf("%s", d.Warning());
- static const char kDescription[] = "stack-overflow";
- Report("ERROR: %s: %s on address %p (pc %p bp %p sp %p T%d)\n",
- SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc,
- (void *)sig.bp, (void *)sig.sp, tid);
- Printf("%s", d.Default());
- InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
- BufferedStackTrace *stack = stack_buffer.data();
- stack->Reset();
- unwind(sig, unwind_context, stack);
- stack->Print();
- ReportErrorSummary(kDescription, stack);
-}
-
-static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,
- UnwindSignalStackCallbackType unwind,
- const void *unwind_context) {
- SanitizerCommonDecorator d;
- Printf("%s", d.Warning());
- const char *description = sig.Describe();
- Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n",
- SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc,
- (void *)sig.bp, (void *)sig.sp, tid);
- Printf("%s", d.Default());
- if (sig.pc < GetPageSizeCached())
- Report("Hint: pc points to the zero page.\n");
- if (sig.is_memory_access) {
- const char *access_type =
- sig.write_flag == SignalContext::WRITE
- ? "WRITE"
- : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
- Report("The signal is caused by a %s memory access.\n", access_type);
- if (sig.addr < GetPageSizeCached())
- Report("Hint: address points to the zero page.\n");
- }
- MaybeReportNonExecRegion(sig.pc);
- InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
- BufferedStackTrace *stack = stack_buffer.data();
- stack->Reset();
- unwind(sig, unwind_context, stack);
- stack->Print();
- MaybeDumpInstructionBytes(sig.pc);
- MaybeDumpRegisters(sig.context);
- Printf("%s can not provide additional info.\n", SanitizerToolName);
- ReportErrorSummary(description, stack);
-}
-
-void ReportDeadlySignal(const SignalContext &sig, u32 tid,
- UnwindSignalStackCallbackType unwind,
- const void *unwind_context) {
- if (sig.IsStackOverflow())
- ReportStackOverflowImpl(sig, tid, unwind, unwind_context);
- else
- ReportDeadlySignalImpl(sig, tid, unwind, unwind_context);
-}
-
-void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
- UnwindSignalStackCallbackType unwind,
- const void *unwind_context) {
- StartReportDeadlySignal();
- ScopedErrorReportLock rl;
- SignalContext sig(siginfo, context);
- ReportDeadlySignal(sig, tid, unwind, unwind_context);
- Report("ABORTING\n");
- Die();
-}
-
-#endif // !SANITIZER_FUCHSIA && !SANITIZER_GO
-
void WriteToSyslog(const char *msg) {
InternalScopedString msg_copy(kErrorMessageBufferSize);
msg_copy.append("%s", msg);
@@ -329,47 +122,6 @@ void MaybeStartBackgroudThread() {
#endif
}
-static atomic_uintptr_t reporting_thread = {0};
-static StaticSpinMutex CommonSanitizerReportMutex;
-
-ScopedErrorReportLock::ScopedErrorReportLock() {
- uptr current = GetThreadSelf();
- for (;;) {
- uptr expected = 0;
- if (atomic_compare_exchange_strong(&reporting_thread, &expected, current,
- memory_order_relaxed)) {
- // We've claimed reporting_thread so proceed.
- CommonSanitizerReportMutex.Lock();
- return;
- }
-
- if (expected == current) {
- // This is either asynch signal or nested error during error reporting.
- // Fail simple to avoid deadlocks in Report().
-
- // Can't use Report() here because of potential deadlocks in nested
- // signal handlers.
- CatastrophicErrorWrite(SanitizerToolName,
- internal_strlen(SanitizerToolName));
- static const char msg[] = ": nested bug in the same thread, aborting.\n";
- CatastrophicErrorWrite(msg, sizeof(msg) - 1);
-
- internal__exit(common_flags()->exitcode);
- }
-
- internal_sched_yield();
- }
-}
-
-ScopedErrorReportLock::~ScopedErrorReportLock() {
- CommonSanitizerReportMutex.Unlock();
- atomic_store_relaxed(&reporting_thread, 0);
-}
-
-void ScopedErrorReportLock::CheckLocked() {
- CommonSanitizerReportMutex.CheckLocked();
-}
-
static void (*sandboxing_callback)();
void SetSandboxingCallback(void (*f)()) {
sandboxing_callback = f;
diff --git a/lib/sanitizer_common/sanitizer_coverage_fuchsia.cc b/lib/sanitizer_common/sanitizer_coverage_fuchsia.cc
index f1b63cbd1..86d37f9eb 100644
--- a/lib/sanitizer_common/sanitizer_coverage_fuchsia.cc
+++ b/lib/sanitizer_common/sanitizer_coverage_fuchsia.cc
@@ -1,11 +1,11 @@
-//===-- sanitizer_coverage_fuchsia.cc ------------------------------------===//
+//===-- sanitizer_coverage_fuchsia.cc -------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// Sanitizer Coverage Controller for Trace PC Guard, Fuchsia-specific version.
//
diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc
index 3c5f29b28..8a41d235c 100644
--- a/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc
+++ b/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc
@@ -16,7 +16,6 @@
#include "sanitizer_atomic.h"
#include "sanitizer_common.h"
#include "sanitizer_file.h"
-#include "sanitizer_symbolizer.h"
using namespace __sanitizer;
diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc
index a4a51f1da..11b29c6e7 100644
--- a/lib/sanitizer_common/sanitizer_fuchsia.cc
+++ b/lib/sanitizer_common/sanitizer_fuchsia.cc
@@ -1,16 +1,16 @@
-//===-- sanitizer_fuchsia.cc ---------------------------------------------===//
+//===-- sanitizer_fuchsia.cc ----------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and other sanitizer
// run-time libraries and implements Fuchsia-specific functions from
// sanitizer_common.h.
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "sanitizer_fuchsia.h"
#if SANITIZER_FUCHSIA
@@ -18,13 +18,11 @@
#include "sanitizer_common.h"
#include "sanitizer_libc.h"
#include "sanitizer_mutex.h"
-#include "sanitizer_stacktrace.h"
#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
-#include <unwind.h>
#include <zircon/errors.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
@@ -92,10 +90,6 @@ void MaybeReexec() {}
void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
void DisableCoreDumperIfNecessary() {}
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
-void StartReportDeadlySignal() {}
-void ReportDeadlySignal(const SignalContext &sig, u32 tid,
- UnwindSignalStackCallbackType unwind,
- const void *unwind_context) {}
void SetAlternateSignalStack() {}
void UnsetAlternateSignalStack() {}
void InitTlsSize() {}
@@ -106,42 +100,6 @@ bool SignalContext::IsStackOverflow() const { return false; }
void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); }
const char *SignalContext::Describe() const { UNIMPLEMENTED(); }
-struct UnwindTraceArg {
- BufferedStackTrace *stack;
- u32 max_depth;
-};
-
-_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
- UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
- CHECK_LT(arg->stack->size, arg->max_depth);
- uptr pc = _Unwind_GetIP(ctx);
- if (pc < PAGE_SIZE) return _URC_NORMAL_STOP;
- arg->stack->trace_buffer[arg->stack->size++] = pc;
- return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
- : _URC_NO_REASON);
-}
-
-void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
- CHECK_GE(max_depth, 2);
- size = 0;
- UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
- _Unwind_Backtrace(Unwind_Trace, &arg);
- CHECK_GT(size, 0);
- // We need to pop a few frames so that pc is on top.
- uptr to_pop = LocatePcInTrace(pc);
- // trace_buffer[0] belongs to the current function so we always pop it,
- // unless there is only 1 frame in the stack trace (1 frame is always better
- // than 0!).
- PopStackFrames(Min(to_pop, static_cast<uptr>(1)));
- trace_buffer[0] = pc;
-}
-
-void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
- u32 max_depth) {
- CHECK_NE(context, nullptr);
- UNREACHABLE("signal context doesn't exist");
-}
-
enum MutexState : int { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
BlockingMutex::BlockingMutex() {
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 8585e2661..06696181e 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -14,7 +14,7 @@
#include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_OPENBSD || SANITIZER_SOLARIS
#include "sanitizer_common.h"
@@ -26,8 +26,6 @@
#include "sanitizer_mutex.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"
-#include "sanitizer_stacktrace.h"
-#include "sanitizer_symbolizer.h"
#if SANITIZER_LINUX
#include <asm/param.h>
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index a5980edd0..8647724f2 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -26,7 +26,6 @@
#include "sanitizer_linux.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"
-#include "sanitizer_stacktrace.h"
#include <dlfcn.h> // for dlsym()
#include <link.h>
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index 0a0f63866..ad0b4d0ea 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -21,7 +21,6 @@
#include "sanitizer_libc.h"
#include "sanitizer_posix.h"
#include "sanitizer_procmaps.h"
-#include "sanitizer_stacktrace.h"
#include <errno.h>
#include <fcntl.h>
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_symbolizer_fuchsia.cc
index 3d1117d9d..3a1227e9c 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_fuchsia.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer_fuchsia.cc
@@ -16,8 +16,12 @@
#if SANITIZER_FUCHSIA
#include "sanitizer_fuchsia.h"
+#include "sanitizer_stacktrace.h"
#include "sanitizer_symbolizer.h"
+#include <limits.h>
+#include <unwind.h>
+
namespace __sanitizer {
// For Fuchsia we don't do any actual symbolization per se.
@@ -102,6 +106,47 @@ Symbolizer *Symbolizer::PlatformInit() {
void Symbolizer::LateInitialize() { Symbolizer::GetOrInit(); }
+void StartReportDeadlySignal() {}
+void ReportDeadlySignal(const SignalContext &sig, u32 tid,
+ UnwindSignalStackCallbackType unwind,
+ const void *unwind_context) {}
+
+struct UnwindTraceArg {
+ BufferedStackTrace *stack;
+ u32 max_depth;
+};
+
+_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
+ UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
+ CHECK_LT(arg->stack->size, arg->max_depth);
+ uptr pc = _Unwind_GetIP(ctx);
+ if (pc < PAGE_SIZE) return _URC_NORMAL_STOP;
+ arg->stack->trace_buffer[arg->stack->size++] = pc;
+ return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
+ : _URC_NO_REASON);
+}
+
+void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
+ CHECK_GE(max_depth, 2);
+ size = 0;
+ UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
+ _Unwind_Backtrace(Unwind_Trace, &arg);
+ CHECK_GT(size, 0);
+ // We need to pop a few frames so that pc is on top.
+ uptr to_pop = LocatePcInTrace(pc);
+ // trace_buffer[0] belongs to the current function so we always pop it,
+ // unless there is only 1 frame in the stack trace (1 frame is always better
+ // than 0!).
+ PopStackFrames(Min(to_pop, static_cast<uptr>(1)));
+ trace_buffer[0] = pc;
+}
+
+void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
+ u32 max_depth) {
+ CHECK_NE(context, nullptr);
+ UNREACHABLE("signal context doesn't exist");
+}
+
} // namespace __sanitizer
#endif // SANITIZER_FUCHSIA
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_report.cc b/lib/sanitizer_common/sanitizer_symbolizer_report.cc
new file mode 100644
index 000000000..1b218336d
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_symbolizer_report.cc
@@ -0,0 +1,282 @@
+//===-- sanitizer_symbolizer_report.cc ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file is shared between AddressSanitizer and other sanitizer run-time
+/// libraries and implements symbolized reports related functions.
+///
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common.h"
+#include "sanitizer_file.h"
+#include "sanitizer_flags.h"
+#include "sanitizer_procmaps.h"
+#include "sanitizer_report_decorator.h"
+#include "sanitizer_stacktrace.h"
+#include "sanitizer_stacktrace_printer.h"
+#include "sanitizer_symbolizer.h"
+
+#if SANITIZER_POSIX
+# include "sanitizer_posix.h"
+# include <sys/mman.h>
+#endif
+
+namespace __sanitizer {
+
+#if !SANITIZER_GO
+void ReportErrorSummary(const char *error_type, const AddressInfo &info,
+ const char *alt_tool_name) {
+ if (!common_flags()->print_summary) return;
+ InternalScopedString buff(kMaxSummaryLength);
+ buff.append("%s ", error_type);
+ RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style,
+ common_flags()->strip_path_prefix);
+ ReportErrorSummary(buff.data(), alt_tool_name);
+}
+#endif
+
+#if !SANITIZER_FUCHSIA
+
+bool ReportFile::SupportsColors() {
+ SpinMutexLock l(mu);
+ ReopenIfNecessary();
+ return SupportsColoredOutput(fd);
+}
+
+static INLINE bool ReportSupportsColors() {
+ return report_file.SupportsColors();
+}
+
+#else // SANITIZER_FUCHSIA
+
+// Fuchsia's logs always go through post-processing that handles colorization.
+static INLINE bool ReportSupportsColors() { return true; }
+
+#endif // !SANITIZER_FUCHSIA
+
+bool ColorizeReports() {
+ // FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color
+ // printing on Windows.
+ if (SANITIZER_WINDOWS)
+ return false;
+
+ const char *flag = common_flags()->color;
+ return internal_strcmp(flag, "always") == 0 ||
+ (internal_strcmp(flag, "auto") == 0 && ReportSupportsColors());
+}
+
+void ReportErrorSummary(const char *error_type, const StackTrace *stack,
+ const char *alt_tool_name) {
+#if !SANITIZER_GO
+ if (!common_flags()->print_summary)
+ return;
+ if (stack->size == 0) {
+ ReportErrorSummary(error_type);
+ return;
+ }
+ // Currently, we include the first stack frame into the report summary.
+ // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc).
+ uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
+ SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
+ ReportErrorSummary(error_type, frame->info, alt_tool_name);
+ frame->ClearAll();
+#endif
+}
+
+void ReportMmapWriteExec(int prot) {
+#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID)
+ if ((prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC))
+ return;
+
+ ScopedErrorReportLock l;
+ SanitizerCommonDecorator d;
+
+ InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
+ BufferedStackTrace *stack = stack_buffer.data();
+ stack->Reset();
+ uptr top = 0;
+ uptr bottom = 0;
+ GET_CALLER_PC_BP_SP;
+ (void)sp;
+ bool fast = common_flags()->fast_unwind_on_fatal;
+ if (fast)
+ GetThreadStackTopAndBottom(false, &top, &bottom);
+ stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, fast);
+
+ Printf("%s", d.Warning());
+ Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName);
+ Printf("%s", d.Default());
+
+ stack->Print();
+ ReportErrorSummary("w-and-x-usage", stack);
+#endif
+}
+
+#if !SANITIZER_FUCHSIA && !SANITIZER_GO
+void StartReportDeadlySignal() {
+ // Write the first message using fd=2, just in case.
+ // It may actually fail to write in case stderr is closed.
+ CatastrophicErrorWrite(SanitizerToolName, internal_strlen(SanitizerToolName));
+ static const char kDeadlySignal[] = ":DEADLYSIGNAL\n";
+ CatastrophicErrorWrite(kDeadlySignal, sizeof(kDeadlySignal) - 1);
+}
+
+static void MaybeReportNonExecRegion(uptr pc) {
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+ MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
+ MemoryMappedSegment segment;
+ while (proc_maps.Next(&segment)) {
+ if (pc >= segment.start && pc < segment.end && !segment.IsExecutable())
+ Report("Hint: PC is at a non-executable region. Maybe a wild jump?\n");
+ }
+#endif
+}
+
+static void PrintMemoryByte(InternalScopedString *str, const char *before,
+ u8 byte) {
+ SanitizerCommonDecorator d;
+ str->append("%s%s%x%x%s ", before, d.MemoryByte(), byte >> 4, byte & 15,
+ d.Default());
+}
+
+static void MaybeDumpInstructionBytes(uptr pc) {
+ if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
+ return;
+ InternalScopedString str(1024);
+ str.append("First 16 instruction bytes at pc: ");
+ if (IsAccessibleMemoryRange(pc, 16)) {
+ for (int i = 0; i < 16; ++i) {
+ PrintMemoryByte(&str, "", ((u8 *)pc)[i]);
+ }
+ str.append("\n");
+ } else {
+ str.append("unaccessible\n");
+ }
+ Report("%s", str.data());
+}
+
+static void MaybeDumpRegisters(void *context) {
+ if (!common_flags()->dump_registers) return;
+ SignalContext::DumpAllRegisters(context);
+}
+
+static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid,
+ UnwindSignalStackCallbackType unwind,
+ const void *unwind_context) {
+ SanitizerCommonDecorator d;
+ Printf("%s", d.Warning());
+ static const char kDescription[] = "stack-overflow";
+ Report("ERROR: %s: %s on address %p (pc %p bp %p sp %p T%d)\n",
+ SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc,
+ (void *)sig.bp, (void *)sig.sp, tid);
+ Printf("%s", d.Default());
+ InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
+ BufferedStackTrace *stack = stack_buffer.data();
+ stack->Reset();
+ unwind(sig, unwind_context, stack);
+ stack->Print();
+ ReportErrorSummary(kDescription, stack);
+}
+
+static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,
+ UnwindSignalStackCallbackType unwind,
+ const void *unwind_context) {
+ SanitizerCommonDecorator d;
+ Printf("%s", d.Warning());
+ const char *description = sig.Describe();
+ Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n",
+ SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc,
+ (void *)sig.bp, (void *)sig.sp, tid);
+ Printf("%s", d.Default());
+ if (sig.pc < GetPageSizeCached())
+ Report("Hint: pc points to the zero page.\n");
+ if (sig.is_memory_access) {
+ const char *access_type =
+ sig.write_flag == SignalContext::WRITE
+ ? "WRITE"
+ : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
+ Report("The signal is caused by a %s memory access.\n", access_type);
+ if (sig.addr < GetPageSizeCached())
+ Report("Hint: address points to the zero page.\n");
+ }
+ MaybeReportNonExecRegion(sig.pc);
+ InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
+ BufferedStackTrace *stack = stack_buffer.data();
+ stack->Reset();
+ unwind(sig, unwind_context, stack);
+ stack->Print();
+ MaybeDumpInstructionBytes(sig.pc);
+ MaybeDumpRegisters(sig.context);
+ Printf("%s can not provide additional info.\n", SanitizerToolName);
+ ReportErrorSummary(description, stack);
+}
+
+void ReportDeadlySignal(const SignalContext &sig, u32 tid,
+ UnwindSignalStackCallbackType unwind,
+ const void *unwind_context) {
+ if (sig.IsStackOverflow())
+ ReportStackOverflowImpl(sig, tid, unwind, unwind_context);
+ else
+ ReportDeadlySignalImpl(sig, tid, unwind, unwind_context);
+}
+
+void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
+ UnwindSignalStackCallbackType unwind,
+ const void *unwind_context) {
+ StartReportDeadlySignal();
+ ScopedErrorReportLock rl;
+ SignalContext sig(siginfo, context);
+ ReportDeadlySignal(sig, tid, unwind, unwind_context);
+ Report("ABORTING\n");
+ Die();
+}
+
+#endif // !SANITIZER_FUCHSIA && !SANITIZER_GO
+
+static atomic_uintptr_t reporting_thread = {0};
+static StaticSpinMutex CommonSanitizerReportMutex;
+
+ScopedErrorReportLock::ScopedErrorReportLock() {
+ uptr current = GetThreadSelf();
+ for (;;) {
+ uptr expected = 0;
+ if (atomic_compare_exchange_strong(&reporting_thread, &expected, current,
+ memory_order_relaxed)) {
+ // We've claimed reporting_thread so proceed.
+ CommonSanitizerReportMutex.Lock();
+ return;
+ }
+
+ if (expected == current) {
+ // This is either asynch signal or nested error during error reporting.
+ // Fail simple to avoid deadlocks in Report().
+
+ // Can't use Report() here because of potential deadlocks in nested
+ // signal handlers.
+ CatastrophicErrorWrite(SanitizerToolName,
+ internal_strlen(SanitizerToolName));
+ static const char msg[] = ": nested bug in the same thread, aborting.\n";
+ CatastrophicErrorWrite(msg, sizeof(msg) - 1);
+
+ internal__exit(common_flags()->exitcode);
+ }
+
+ internal_sched_yield();
+ }
+}
+
+ScopedErrorReportLock::~ScopedErrorReportLock() {
+ CommonSanitizerReportMutex.Unlock();
+ atomic_store_relaxed(&reporting_thread, 0);
+}
+
+void ScopedErrorReportLock::CheckLocked() {
+ CommonSanitizerReportMutex.CheckLocked();
+}
+
+} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt
index 1bccaa78f..9f2cb39fb 100644
--- a/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/lib/sanitizer_common/tests/CMakeLists.txt
@@ -178,7 +178,8 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
if(APPLE)
add_sanitizer_common_lib("RTSanitizerCommon.test.osx"
$<TARGET_OBJECTS:RTSanitizerCommon.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>)
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>)
else()
if(CAN_TARGET_x86_64)
add_sanitizer_common_lib("RTSanitizerCommon.test.nolibc.x86_64"
@@ -188,7 +189,8 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
add_sanitizer_common_lib("RTSanitizerCommon.test.${arch}"
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
endforeach()
endif()
foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
@@ -202,7 +204,8 @@ if(ANDROID)
${SANITIZER_UNITTESTS}
${COMPILER_RT_GTEST_SOURCE}
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
set_target_compile_flags(SanitizerTest
${SANITIZER_COMMON_CFLAGS}
${SANITIZER_TEST_CFLAGS_COMMON})
diff --git a/lib/scudo/CMakeLists.txt b/lib/scudo/CMakeLists.txt
index 1e03fcd40..3adfe6882 100644
--- a/lib/scudo/CMakeLists.txt
+++ b/lib/scudo/CMakeLists.txt
@@ -25,10 +25,11 @@ set(SCUDO_OBJECT_LIBS
if (FUCHSIA)
list(APPEND SCUDO_CFLAGS -nostdinc++)
list(APPEND SCUDO_DYNAMIC_LINK_FLAGS -nostdlib++)
- # TODO(kostyak): remove when stacktraces are split off of RTSanitizerCommon
- list(APPEND SCUDO_DYNAMIC_LIBS unwind_shared)
else()
- list(APPEND SCUDO_OBJECT_LIBS RTSanitizerCommonCoverage RTUbsan)
+ list(APPEND SCUDO_OBJECT_LIBS
+ RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
+ RTUbsan)
list(APPEND SCUDO_DYNAMIC_LIBS ${SANITIZER_CXX_ABI_LIBRARY})
endif()
diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt
index 4eb72e59b..8a414d472 100644
--- a/lib/tsan/CMakeLists.txt
+++ b/lib/tsan/CMakeLists.txt
@@ -115,6 +115,7 @@ if(APPLE)
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTUbsan
CFLAGS ${TSAN_RTL_CFLAGS}
LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
@@ -174,6 +175,7 @@ else()
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
CFLAGS ${TSAN_RTL_CFLAGS}
PARENT_TARGET tsan)
diff --git a/lib/tsan/go/buildgo.sh b/lib/tsan/go/buildgo.sh
index 2fbbcc12b..87a778c99 100755
--- a/lib/tsan/go/buildgo.sh
+++ b/lib/tsan/go/buildgo.sh
@@ -35,6 +35,7 @@ SRCS="
../../sanitizer_common/sanitizer_stackdepot.cc
../../sanitizer_common/sanitizer_stacktrace.cc
../../sanitizer_common/sanitizer_symbolizer.cc
+ ../../sanitizer_common/sanitizer_symbolizer_report.cc
../../sanitizer_common/sanitizer_termination.cc
"
diff --git a/lib/tsan/tests/CMakeLists.txt b/lib/tsan/tests/CMakeLists.txt
index a451febef..a3d8e9692 100644
--- a/lib/tsan/tests/CMakeLists.txt
+++ b/lib/tsan/tests/CMakeLists.txt
@@ -23,6 +23,7 @@ if(APPLE)
$<TARGET_OBJECTS:RTSanitizerCommon.osx>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>
$<TARGET_OBJECTS:RTUbsan.osx>)
set(TSAN_TEST_RUNTIME RTTsanTest)
add_library(${TSAN_TEST_RUNTIME} STATIC ${TSAN_TEST_RUNTIME_OBJECTS})
diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt
index 04618030e..5e5eb7dca 100644
--- a/lib/ubsan/CMakeLists.txt
+++ b/lib/ubsan/CMakeLists.txt
@@ -77,6 +77,7 @@ if(APPLE)
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTInterception
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
PARENT_TARGET ubsan)
@@ -90,6 +91,7 @@ if(APPLE)
RTSanitizerCommonNoHooks
RTSanitizerCommonLibcNoHooks
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTInterception
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
PARENT_TARGET ubsan)
@@ -157,6 +159,7 @@ else()
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTUbsan
RTUbsan_standalone
RTInterception
@@ -177,6 +180,7 @@ else()
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
RTUbsan
RTUbsan_cxx
RTUbsan_standalone