summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2013-10-25 23:03:29 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2013-10-25 23:03:29 +0000
commitc1a1ed62228288155459d39194995a36aca4a8a6 (patch)
tree4bb3144d74f7d3db0bcfcecc867ed7b13e83e3f0
parent8f0c5bdd9650256501bad9fc5dedc977f4ca2247 (diff)
downloadcompiler-rt-c1a1ed62228288155459d39194995a36aca4a8a6.tar.gz
compiler-rt-c1a1ed62228288155459d39194995a36aca4a8a6.tar.bz2
compiler-rt-c1a1ed62228288155459d39194995a36aca4a8a6.tar.xz
Overhaul the symbolizer interface.
This moves away from creating the symbolizer object and initializing the external symbolizer as separate steps. Those steps now always take place together. Sanitizers with a legacy requirement to specify their own symbolizer path should use InitSymbolizer to initialize the symbolizer with the desired path, and GetSymbolizer to access the symbolizer. Sanitizers with no such requirement (e.g. UBSan) can use GetOrInitSymbolizer with no need for initialization. The symbolizer interface has been made thread-safe (as far as I can tell) by protecting its member functions with mutexes. Finally, the symbolizer interface no longer relies on weak externals, the introduction of which was probably a mistake on my part. Differential Revision: http://llvm-reviews.chandlerc.com/D1985 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193448 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/CMakeLists.txt2
-rw-r--r--lib/asan/asan_report.cc8
-rw-r--r--lib/asan/asan_rtl.cc7
-rw-r--r--lib/lsan/lsan.cc5
-rw-r--r--lib/lsan/lsan_common.cc4
-rw-r--r--lib/msan/msan.cc6
-rw-r--r--lib/msan/msan_report.cc6
-rw-r--r--lib/sanitizer_common/CMakeLists.txt2
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc3
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.cc7
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.cc43
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.h43
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc47
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc91
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_win.cc7
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc6
-rw-r--r--lib/tsan/rtl/tsan_symbolize.cc14
-rw-r--r--lib/ubsan/lit_tests/CMakeLists.txt1
-rw-r--r--lib/ubsan/lit_tests/TypeCheck/Function/function.cpp2
-rw-r--r--lib/ubsan/lit_tests/lit.cfg3
-rw-r--r--lib/ubsan/ubsan_diag.cc4
21 files changed, 207 insertions, 104 deletions
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
index 7a54f96f..17552b3a 100644
--- a/lib/asan/CMakeLists.txt
+++ b/lib/asan/CMakeLists.txt
@@ -137,8 +137,6 @@ endif()
add_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt)
-add_custom_target(asan DEPENDS asan_blacklist ${ASAN_RUNTIME_LIBRARIES})
-
if(LLVM_INCLUDE_TESTS)
add_subdirectory(tests)
endif()
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 3b410ca7..5406ac02 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -181,8 +181,8 @@ static bool IsASCII(unsigned char c) {
static const char *MaybeDemangleGlobalName(const char *name) {
// We can spoil names of globals with C linkage, so use an heuristic
// approach to check if the name should be demangled.
- return (name[0] == '_' && name[1] == 'Z' && &getSymbolizer)
- ? getSymbolizer()->Demangle(name)
+ return (name[0] == '_' && name[1] == 'Z')
+ ? Symbolizer::Get()->Demangle(name)
: name;
}
@@ -551,11 +551,11 @@ class ScopedInErrorReport {
static void ReportSummary(const char *error_type, StackTrace *stack) {
AddressInfo ai;
- if (&getSymbolizer && getSymbolizer()->IsAvailable()) {
+ if (Symbolizer::Get()->IsAvailable()) {
// 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]);
- getSymbolizer()->SymbolizeCode(pc, &ai, 1);
+ Symbolizer::Get()->SymbolizeCode(pc, &ai, 1);
}
ReportErrorSummary(error_type, ai.file, ai.line, ai.function);
}
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index 2b4114a0..db680215 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -536,9 +536,10 @@ void __asan_init() {
InitializeAllocator();
// Start symbolizer process if necessary.
- if (common_flags()->symbolize && &getSymbolizer) {
- getSymbolizer()
- ->InitializeExternal(common_flags()->external_symbolizer_path);
+ if (common_flags()->symbolize) {
+ Symbolizer::Init(common_flags()->external_symbolizer_path);
+ } else {
+ Symbolizer::Disable();
}
// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cc
index 7f37da6c..3006f04f 100644
--- a/lib/lsan/lsan.cc
+++ b/lib/lsan/lsan.cc
@@ -53,8 +53,9 @@ void Init() {
// Start symbolizer process if necessary.
if (common_flags()->symbolize) {
- getSymbolizer()
- ->InitializeExternal(common_flags()->external_symbolizer_path);
+ Symbolizer::Init(common_flags()->external_symbolizer_path);
+ } else {
+ Symbolizer::Disable();
}
InitCommonLsan();
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 8a4ec7a3..8a3bc2e3 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -413,8 +413,8 @@ static Suppression *GetSuppressionForAddr(uptr addr) {
static const uptr kMaxAddrFrames = 16;
InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
for (uptr i = 0; i < kMaxAddrFrames; i++) new (&addr_frames[i]) AddressInfo();
- uptr addr_frames_num =
- getSymbolizer()->SymbolizeCode(addr, addr_frames.data(), kMaxAddrFrames);
+ uptr addr_frames_num = Symbolizer::Get()->SymbolizeCode(
+ addr, addr_frames.data(), kMaxAddrFrames);
for (uptr i = 0; i < addr_frames_num; i++) {
Suppression* s;
if (suppression_ctx->Match(addr_frames[i].function, SuppressionLeak, &s) ||
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index c13a95d9..7865044c 100644
--- a/lib/msan/msan.cc
+++ b/lib/msan/msan.cc
@@ -331,10 +331,10 @@ void __msan_init() {
}
const char *external_symbolizer = common_flags()->external_symbolizer_path;
- bool symbolizer_started =
- getSymbolizer()->InitializeExternal(external_symbolizer);
+ bool external_symbolizer_started =
+ Symbolizer::Init(external_symbolizer)->IsExternalAvailable();
if (external_symbolizer && external_symbolizer[0]) {
- CHECK(symbolizer_started);
+ CHECK(external_symbolizer_started);
}
GetThreadStackTopAndBottom(/* at_initialization */true,
diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cc
index 575cfc22..354bc80b 100644
--- a/lib/msan/msan_report.cc
+++ b/lib/msan/msan_report.cc
@@ -54,7 +54,7 @@ static void DescribeOrigin(u32 origin) {
Printf(" %sUninitialized value was created by an allocation of '%s%s%s'"
" in the stack frame of function '%s%s%s'%s\n",
d.Origin(), d.Name(), s, d.Origin(), d.Name(),
- getSymbolizer()->Demangle(sep + 1), d.Origin(), d.End());
+ Symbolizer::Get()->Demangle(sep + 1), d.Origin(), d.End());
InternalFree(s);
if (pc) {
@@ -73,12 +73,12 @@ static void DescribeOrigin(u32 origin) {
}
static void ReportSummary(const char *error_type, StackTrace *stack) {
- if (!stack->size || !getSymbolizer()->IsAvailable()) return;
+ if (!stack->size || !Symbolizer::Get()->IsAvailable()) return;
AddressInfo ai;
uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
{
SymbolizerScope sym_scope;
- getSymbolizer()->SymbolizeCode(pc, &ai, 1);
+ Symbolizer::Get()->SymbolizeCode(pc, &ai, 1);
}
ReportErrorSummary(error_type, ai.file, ai.line, ai.function);
}
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
index 6a960c92..923cf234 100644
--- a/lib/sanitizer_common/CMakeLists.txt
+++ b/lib/sanitizer_common/CMakeLists.txt
@@ -16,6 +16,7 @@ set(SANITIZER_SOURCES
sanitizer_stackdepot.cc
sanitizer_stacktrace.cc
sanitizer_suppressions.cc
+ sanitizer_symbolizer.cc
sanitizer_symbolizer_win.cc
sanitizer_thread_registry.cc
sanitizer_win.cc)
@@ -25,6 +26,7 @@ set(SANITIZER_LIBCDEP_SOURCES
sanitizer_linux_libcdep.cc
sanitizer_posix_libcdep.cc
sanitizer_stoptheworld_linux_libcdep.cc
+ sanitizer_symbolizer_libcdep.cc
sanitizer_symbolizer_posix_libcdep.cc)
# Explicitly list all sanitizer_common headers. Not all of these are
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 080945d2..fd0cf7fb 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -312,7 +312,8 @@ void PrepareForSandboxing() {
MemoryMappingLayout::CacheMemoryMappings();
// Same for /proc/self/exe in the symbolizer.
#if !SANITIZER_GO
- getSymbolizer()->PrepareForSandboxing();
+ if (Symbolizer *sym = Symbolizer::GetOrNull())
+ sym->PrepareForSandboxing();
#endif
}
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.cc b/lib/sanitizer_common/sanitizer_stacktrace.cc
index f67df7e9..2e9640b8 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace.cc
@@ -62,10 +62,11 @@ void StackTrace::PrintStack(const uptr *addr, uptr size, bool symbolize,
frame_num++;
}
}
- if (symbolize && addr_frames_num == 0 && &getSymbolizer) {
+ if (symbolize && addr_frames_num == 0) {
// Use our own (online) symbolizer, if necessary.
- addr_frames_num = getSymbolizer()->SymbolizeCode(
- pc, addr_frames.data(), addr_frames.size());
+ if (Symbolizer *sym = Symbolizer::GetOrNull())
+ addr_frames_num =
+ sym->SymbolizeCode(pc, addr_frames.data(), addr_frames.size());
for (uptr j = 0; j < addr_frames_num; j++) {
AddressInfo &info = addr_frames[j];
PrintStackFramePrefix(frame_num, pc);
diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cc
new file mode 100644
index 00000000..95ebfebe
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_symbolizer.cc
@@ -0,0 +1,43 @@
+//===-- sanitizer_symbolizer.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 ThreadSanitizer
+// run-time libraries.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_placement_new.h"
+#include "sanitizer_symbolizer.h"
+
+namespace __sanitizer {
+
+atomic_uintptr_t Symbolizer::symbolizer_;
+LowLevelAllocator Symbolizer::symbolizer_allocator_;
+
+Symbolizer *Symbolizer::GetOrNull() {
+ return reinterpret_cast<Symbolizer *>(
+ atomic_load(&symbolizer_, memory_order_acquire));
+}
+
+Symbolizer *Symbolizer::Get() {
+ Symbolizer *sym = GetOrNull();
+ CHECK(sym);
+ return sym;
+}
+
+Symbolizer *Symbolizer::Disable() {
+ CHECK_EQ(0, atomic_load(&symbolizer_, memory_order_acquire));
+ Symbolizer *dummy_sym = new(symbolizer_allocator_) Symbolizer;
+ atomic_store(&symbolizer_, reinterpret_cast<uptr>(&dummy_sym),
+ memory_order_release);
+ return dummy_sym;
+}
+
+} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h
index 383e1d4a..ea2fc6a6 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer.h
+++ b/lib/sanitizer_common/sanitizer_symbolizer.h
@@ -69,8 +69,24 @@ struct DataInfo {
uptr size;
};
-class SymbolizerInterface {
+class Symbolizer {
public:
+ /// Returns platform-specific implementation of Symbolizer. The symbolizer
+ /// must be initialized (with init or disable) before calling this function.
+ static Symbolizer *Get();
+ /// Returns platform-specific implementation of Symbolizer, or null if not
+ /// initialized.
+ static Symbolizer *GetOrNull();
+ /// Returns platform-specific implementation of Symbolizer. Will
+ /// automatically initialize symbolizer as if by calling Init(0) if needed.
+ static Symbolizer *GetOrInit();
+ /// Initialize and return the symbolizer, given an optional path to an
+ /// external symbolizer. The path argument is only required for legacy
+ /// reasons as this function will check $PATH for an external symbolizer. Not
+ /// thread safe.
+ static Symbolizer *Init(const char* path_to_external = 0);
+ /// Initialize the symbolizer in a disabled state. Not thread safe.
+ static Symbolizer *Disable();
// Fills at most "max_frames" elements of "frames" with descriptions
// for a given address (in all inlined functions). Returns the number
// of descriptions actually filled.
@@ -84,6 +100,9 @@ class SymbolizerInterface {
virtual bool IsAvailable() {
return false;
}
+ virtual bool IsExternalAvailable() {
+ return false;
+ }
// Release internal caches (if any).
virtual void Flush() {}
// Attempts to demangle the provided C++ mangled name.
@@ -91,17 +110,19 @@ class SymbolizerInterface {
return name;
}
virtual void PrepareForSandboxing() {}
- // Starts external symbolizer program in a subprocess. Sanitizer communicates
- // with external symbolizer via pipes. If path_to_symbolizer is NULL or empty,
- // tries to look for llvm-symbolizer in PATH.
- virtual bool InitializeExternal(const char *path_to_symbolizer) {
- return false;
- }
-};
-// Returns platform-specific implementation of SymbolizerInterface. It can't be
-// used from multiple threads simultaneously.
-SANITIZER_WEAK_ATTRIBUTE SymbolizerInterface *getSymbolizer();
+ private:
+ /// Platform-specific function for creating a Symbolizer object.
+ static Symbolizer *PlatformInit(const char *path_to_external);
+ /// Create a symbolizer and store it to symbolizer_ without checking if one
+ /// already exists. Not thread safe.
+ static Symbolizer *CreateAndStore(const char *path_to_external);
+
+ static atomic_uintptr_t symbolizer_;
+
+ protected:
+ static LowLevelAllocator symbolizer_allocator_;
+};
} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc
new file mode 100644
index 00000000..ada7be15
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc
@@ -0,0 +1,47 @@
+//===-- sanitizer_symbolizer_libcdep.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 ThreadSanitizer
+// run-time libraries.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_placement_new.h"
+#include "sanitizer_symbolizer.h"
+
+namespace __sanitizer {
+
+Symbolizer *Symbolizer::CreateAndStore(const char *path_to_external) {
+ Symbolizer *platform_symbolizer = PlatformInit(path_to_external);
+ if (!platform_symbolizer) return Disable();
+ atomic_store(&symbolizer_, reinterpret_cast<uptr>(platform_symbolizer),
+ memory_order_release);
+ return platform_symbolizer;
+}
+
+Symbolizer *Symbolizer::Init(const char *path_to_external) {
+ CHECK_EQ(0, atomic_load(&symbolizer_, memory_order_acquire));
+ return CreateAndStore(path_to_external);
+}
+
+Symbolizer *Symbolizer::GetOrInit() {
+ static StaticSpinMutex init_mu;
+
+ uptr sym = atomic_load(&symbolizer_, memory_order_acquire);
+ if (!sym) {
+ SpinMutexLock l(&init_mu);
+ sym = atomic_load(&symbolizer_, memory_order_relaxed);
+ if (!sym) return CreateAndStore(0);
+ }
+
+ return reinterpret_cast<Symbolizer *>(sym);
+}
+
+} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
index 9b50e115..206de863 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
@@ -285,8 +285,6 @@ class ExternalSymbolizer {
uptr times_restarted_;
};
-static LowLevelAllocator symbolizer_allocator; // Linker initialized.
-
#if SANITIZER_SUPPORTS_WEAK_HOOKS
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
@@ -306,11 +304,10 @@ class InternalSymbolizer {
public:
typedef bool (*SanitizerSymbolizeFn)(const char*, u64, char*, int);
- static InternalSymbolizer *get() {
+ static InternalSymbolizer *get(LowLevelAllocator *alloc) {
if (__sanitizer_symbolize_code != 0 &&
__sanitizer_symbolize_data != 0) {
- void *mem = symbolizer_allocator.Allocate(sizeof(InternalSymbolizer));
- return new(mem) InternalSymbolizer();
+ return new(*alloc) InternalSymbolizer();
}
return 0;
}
@@ -357,7 +354,7 @@ class InternalSymbolizer {
class InternalSymbolizer {
public:
- static InternalSymbolizer *get() { return 0; }
+ static InternalSymbolizer *get(LowLevelAllocator *alloc) { return 0; }
char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
return 0;
}
@@ -367,11 +364,15 @@ class InternalSymbolizer {
#endif // SANITIZER_SUPPORTS_WEAK_HOOKS
-class Symbolizer : public SymbolizerInterface {
- // This class has no constructor, as global constructors are forbidden in
- // sanitizer_common. It should be linker initialized instead.
+class POSIXSymbolizer : public Symbolizer {
public:
+ POSIXSymbolizer(ExternalSymbolizer *external_symbolizer,
+ InternalSymbolizer *internal_symbolizer)
+ : external_symbolizer_(external_symbolizer),
+ internal_symbolizer_(internal_symbolizer) {}
+
uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) {
+ BlockingMutexLock l(&mu_);
if (max_frames == 0)
return 0;
LoadedModule *module = FindModuleForAddress(addr);
@@ -432,6 +433,7 @@ class Symbolizer : public SymbolizerInterface {
}
bool SymbolizeData(uptr addr, DataInfo *info) {
+ BlockingMutexLock l(&mu_);
LoadedModule *module = FindModuleForAddress(addr);
if (module == 0)
return false;
@@ -451,42 +453,32 @@ class Symbolizer : public SymbolizerInterface {
return true;
}
- bool InitializeExternal(const char *path_to_symbolizer) {
- if (!path_to_symbolizer || path_to_symbolizer[0] == '\0') {
- path_to_symbolizer = FindPathToBinary("llvm-symbolizer");
- if (!path_to_symbolizer)
- return false;
- }
- int input_fd, output_fd;
- if (!StartSymbolizerSubprocess(path_to_symbolizer, &input_fd, &output_fd))
- return false;
- void *mem = symbolizer_allocator.Allocate(sizeof(ExternalSymbolizer));
- external_symbolizer_ = new(mem) ExternalSymbolizer(path_to_symbolizer,
- input_fd, output_fd);
- return true;
+ bool IsAvailable() {
+ return internal_symbolizer_ != 0 || external_symbolizer_ != 0;
}
- bool IsAvailable() {
- if (internal_symbolizer_ == 0)
- internal_symbolizer_ = InternalSymbolizer::get();
- return internal_symbolizer_ || external_symbolizer_;
+ bool IsExternalAvailable() {
+ return external_symbolizer_ != 0;
}
void Flush() {
- if (internal_symbolizer_)
+ BlockingMutexLock l(&mu_);
+ if (internal_symbolizer_ != 0)
internal_symbolizer_->Flush();
- if (external_symbolizer_)
+ if (external_symbolizer_ != 0)
external_symbolizer_->Flush();
}
const char *Demangle(const char *name) {
- if (IsAvailable() && internal_symbolizer_ != 0)
+ BlockingMutexLock l(&mu_);
+ if (internal_symbolizer_ != 0)
return internal_symbolizer_->Demangle(name);
return DemangleCXXABI(name);
}
void PrepareForSandboxing() {
#if SANITIZER_LINUX && !SANITIZER_ANDROID
+ BlockingMutexLock l(&mu_);
// Cache /proc/self/exe on Linux.
CacheBinaryName();
#endif
@@ -494,10 +486,8 @@ class Symbolizer : public SymbolizerInterface {
private:
char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
+ mu_.CheckLocked();
// First, try to use internal symbolizer.
- if (!IsAvailable()) {
- return 0;
- }
if (internal_symbolizer_) {
return internal_symbolizer_->SendCommand(is_data, module_name,
module_offset);
@@ -526,9 +516,10 @@ class Symbolizer : public SymbolizerInterface {
}
LoadedModule *FindModuleForAddress(uptr address) {
+ mu_.CheckLocked();
bool modules_were_reloaded = false;
if (modules_ == 0 || !modules_fresh_) {
- modules_ = (LoadedModule*)(symbolizer_allocator.Allocate(
+ modules_ = (LoadedModule*)(symbolizer_allocator_.Allocate(
kMaxNumberOfModuleContexts * sizeof(LoadedModule)));
CHECK(modules_);
n_modules_ = GetListOfModules(modules_, kMaxNumberOfModuleContexts,
@@ -571,25 +562,31 @@ class Symbolizer : public SymbolizerInterface {
uptr n_modules_;
// If stale, need to reload the modules before looking up addresses.
bool modules_fresh_;
+ BlockingMutex mu_;
- ExternalSymbolizer *external_symbolizer_; // Leaked.
- InternalSymbolizer *internal_symbolizer_; // Leaked.
+ ExternalSymbolizer *external_symbolizer_; // Leaked.
+ InternalSymbolizer *const internal_symbolizer_; // Leaked.
};
-static ALIGNED(64) char symbolizer_placeholder[sizeof(Symbolizer)];
-static Symbolizer *symbolizer;
-
-SymbolizerInterface *getSymbolizer() {
- static atomic_uint8_t initialized;
- static StaticSpinMutex init_mu;
- if (atomic_load(&initialized, memory_order_acquire) == 0) {
- SpinMutexLock l(&init_mu);
- if (atomic_load(&initialized, memory_order_relaxed) == 0) {
- symbolizer = new(symbolizer_placeholder) Symbolizer();
- atomic_store(&initialized, 1, memory_order_release);
+Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) {
+ InternalSymbolizer* internal_symbolizer =
+ InternalSymbolizer::get(&symbolizer_allocator_);
+ ExternalSymbolizer *external_symbolizer = 0;
+
+ if (!internal_symbolizer) {
+ if (!path_to_external || path_to_external[0] == '\0')
+ path_to_external = FindPathToBinary("llvm-symbolizer");
+
+ int input_fd, output_fd;
+ if (path_to_external &&
+ StartSymbolizerSubprocess(path_to_external, &input_fd, &output_fd)) {
+ external_symbolizer = new(symbolizer_allocator_)
+ ExternalSymbolizer(path_to_external, input_fd, output_fd);
}
}
- return symbolizer;
+
+ return new(symbolizer_allocator_)
+ POSIXSymbolizer(external_symbolizer, internal_symbolizer);
}
} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_win.cc b/lib/sanitizer_common/sanitizer_symbolizer_win.cc
index de7a5b9c..5d451eff 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer_win.cc
@@ -14,16 +14,11 @@
#include "sanitizer_platform.h"
#if SANITIZER_WINDOWS
-#include "sanitizer_internal_defs.h"
#include "sanitizer_symbolizer.h"
namespace __sanitizer {
-static SymbolizerInterface win_symbolizer; // Linker initialized.
-
-SymbolizerInterface *getSymbolizer() {
- return &win_symbolizer;
-}
+Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) { return 0; }
} // namespace __sanitizer
diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc
index 22cf3cfc..fc2aa767 100644
--- a/lib/tsan/rtl/tsan_rtl.cc
+++ b/lib/tsan/rtl/tsan_rtl.cc
@@ -238,10 +238,10 @@ void Initialize(ThreadState *thr) {
InitializeLibIgnore();
// Initialize external symbolizer before internal threads are started.
const char *external_symbolizer = flags()->external_symbolizer_path;
- bool symbolizer_started =
- getSymbolizer()->InitializeExternal(external_symbolizer);
+ bool external_symbolizer_started =
+ Symbolizer::Init(external_symbolizer)->IsExternalAvailable();
if (external_symbolizer != 0 && external_symbolizer[0] != '\0' &&
- !symbolizer_started) {
+ !external_symbolizer_started) {
Printf("Failed to start external symbolizer: '%s'\n",
external_symbolizer);
Die();
diff --git a/lib/tsan/rtl/tsan_symbolize.cc b/lib/tsan/rtl/tsan_symbolize.cc
index 4e997e71..a2ed5d05 100644
--- a/lib/tsan/rtl/tsan_symbolize.cc
+++ b/lib/tsan/rtl/tsan_symbolize.cc
@@ -119,15 +119,15 @@ ReportStack *SymbolizeCode(uptr addr) {
ent->col = col;
return ent;
}
- if (!getSymbolizer()->IsAvailable())
+ if (!Symbolizer::Get()->IsAvailable())
return SymbolizeCodeAddr2Line(addr);
ScopedInSymbolizer in_symbolizer;
static const uptr kMaxAddrFrames = 16;
InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
for (uptr i = 0; i < kMaxAddrFrames; i++)
new(&addr_frames[i]) AddressInfo();
- uptr addr_frames_num =
- getSymbolizer()->SymbolizeCode(addr, addr_frames.data(), kMaxAddrFrames);
+ uptr addr_frames_num = Symbolizer::Get()->SymbolizeCode(
+ addr, addr_frames.data(), kMaxAddrFrames);
if (addr_frames_num == 0)
return NewReportStackEntry(addr);
ReportStack *top = 0;
@@ -146,11 +146,11 @@ ReportStack *SymbolizeCode(uptr addr) {
}
ReportLocation *SymbolizeData(uptr addr) {
- if (!getSymbolizer()->IsAvailable())
+ if (!Symbolizer::Get()->IsAvailable())
return 0;
ScopedInSymbolizer in_symbolizer;
DataInfo info;
- if (!getSymbolizer()->SymbolizeData(addr, &info))
+ if (!Symbolizer::Get()->SymbolizeData(addr, &info))
return 0;
ReportLocation *ent = (ReportLocation*)internal_alloc(MBlockReportStack,
sizeof(ReportLocation));
@@ -166,10 +166,10 @@ ReportLocation *SymbolizeData(uptr addr) {
}
void SymbolizeFlush() {
- if (!getSymbolizer()->IsAvailable())
+ if (!Symbolizer::Get()->IsAvailable())
return;
ScopedInSymbolizer in_symbolizer;
- getSymbolizer()->Flush();
+ Symbolizer::Get()->Flush();
}
} // namespace __tsan
diff --git a/lib/ubsan/lit_tests/CMakeLists.txt b/lib/ubsan/lit_tests/CMakeLists.txt
index 6abc8a01..7e1a13c7 100644
--- a/lib/ubsan/lit_tests/CMakeLists.txt
+++ b/lib/ubsan/lit_tests/CMakeLists.txt
@@ -8,7 +8,6 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
# working binaries.
set(UBSAN_TEST_DEPS
${SANITIZER_COMMON_LIT_TEST_DEPS}
- asan
${UBSAN_RUNTIME_LIBRARIES})
set(UBSAN_TEST_PARAMS
ubsan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
diff --git a/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp b/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp
index feff0f5a..8106ae47 100644
--- a/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp
+++ b/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=address,function %s -O3 -g -o %t
+// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
// RUN: %t 2>&1 | FileCheck %s
#include <stdint.h>
diff --git a/lib/ubsan/lit_tests/lit.cfg b/lib/ubsan/lit_tests/lit.cfg
index d96912fe..4a5bc237 100644
--- a/lib/ubsan/lit_tests/lit.cfg
+++ b/lib/ubsan/lit_tests/lit.cfg
@@ -54,9 +54,6 @@ config.substitutions.append( ("%clang ", (" " + config.clang + " ")) )
config.substitutions.append( ("%clangxx ", (" " + config.clang +
" --driver-mode=g++ ")) )
-# Setup path to external LLVM symbolizer.
-config.environment['ASAN_SYMBOLIZER_PATH'] = config.llvm_symbolizer_path
-
# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']
diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc
index 968e7790..158408b7 100644
--- a/lib/ubsan/ubsan_diag.cc
+++ b/lib/ubsan/ubsan_diag.cc
@@ -34,7 +34,7 @@ Location __ubsan::getFunctionLocation(uptr Loc, const char **FName) {
return Location();
AddressInfo Info;
- if (!getSymbolizer()->SymbolizeCode(Loc, &Info, 1) ||
+ if (!Symbolizer::GetOrInit()->SymbolizeCode(Loc, &Info, 1) ||
!Info.module || !*Info.module)
return Location(Loc);
@@ -117,7 +117,7 @@ static void renderText(const char *Message, const Diag::Arg *Args) {
Printf("%s", A.String);
break;
case Diag::AK_Mangled: {
- Printf("'%s'", getSymbolizer()->Demangle(A.String));
+ Printf("'%s'", Symbolizer::GetOrInit()->Demangle(A.String));
break;
}
case Diag::AK_SInt: