[sanitizer] Fix a crash when demangling Swift symbols, take 2

To invoke the Swift demangler, we use dlsym to locate swift_demangle. However, dlsym malloc's storage and stores it in thread-local storage. Since allocations from the symbolizer are done with the system allocator (at least in TSan, interceptors are skipped when inside the symbolizer), we will crash when we try to deallocate later using the sanitizer allocator again.

To fix this, let's just not call dlsym from the demangler, and call it during initialization. The dlsym function calls malloc, so it needs to be only used after our allocator is initialized. Adding a Symbolizer::LateInitialize call that is only invoked after all other initializations.

Differential Revision: http://reviews.llvm.org/D20015

llvm-svn: 269291
This commit is contained in:
Kuba Brecka 2016-05-12 13:11:03 +00:00
parent 89b89650f3
commit 5bdf86ec7c
5 changed files with 32 additions and 14 deletions

View File

@ -553,6 +553,8 @@ static void AsanInitInternal() {
InitializeSuppressions();
Symbolizer::LateInitialize();
VReport(1, "AddressSanitizer Init done\n");
}

View File

@ -82,6 +82,7 @@ class Symbolizer final {
/// Initialize and return platform-specific implementation of symbolizer
/// (if it wasn't already initialized).
static Symbolizer *GetOrInit();
static void LateInitialize();
// Returns a list of symbolized frames for a given address (containing
// all inlined functions, if necessary).
SymbolizedStack *SymbolizePC(uptr address);

View File

@ -63,25 +63,29 @@ const char *DemangleCXXABI(const char *name) {
return name;
}
// Attempts to demangle a Swift name. The demangler will return nullptr
/// if a non-Swift name is passed in.
// As of now, there are no headers for the Swift runtime. Once they are
// present, we will weakly link since we do not require Swift runtime to be
// linked.
typedef char *(*swift_demangle_ft)(const char *mangledName,
size_t mangledNameLength, char *outputBuffer,
size_t *outputBufferSize, uint32_t flags);
static swift_demangle_ft swift_demangle_f;
// This must not happen lazily at symbolication time, because dlsym uses
// malloc and thread-local storage, which is not a good thing to do during
// symbolication.
static void InitializeSwiftDemangler() {
swift_demangle_f = (swift_demangle_ft)dlsym(RTLD_DEFAULT, "swift_demangle");
}
// Attempts to demangle a Swift name. The demangler will return nullptr if a
// non-Swift name is passed in.
const char *DemangleSwift(const char *name) {
// Not to call dlsym every time we demangle, check if we are dealing with
// Swift mangled name first.
// Check if we are dealing with a Swift mangled name first.
if (name[0] != '_' || name[1] != 'T') {
return nullptr;
}
// As of now, there are no headers for the Swift runtime. Once they are
// present, we will weakly link since we do not require Swift runtime to be
// linked.
typedef char *(*swift_demangle_ft)(const char *mangledName,
size_t mangledNameLength,
char *outputBuffer,
size_t *outputBufferSize,
uint32_t flags);
swift_demangle_ft swift_demangle_f =
(swift_demangle_ft) dlsym(RTLD_DEFAULT, "swift_demangle");
if (swift_demangle_f)
return swift_demangle_f(name, internal_strlen(name), 0, 0, 0);
@ -485,6 +489,11 @@ Symbolizer *Symbolizer::PlatformInit() {
return new(symbolizer_allocator_) Symbolizer(list);
}
void Symbolizer::LateInitialize() {
Symbolizer::GetOrInit();
InitializeSwiftDemangler();
}
} // namespace __sanitizer
#endif // SANITIZER_POSIX

View File

@ -279,6 +279,10 @@ Symbolizer *Symbolizer::PlatformInit() {
return new(symbolizer_allocator_) Symbolizer(list);
}
void Symbolizer::LateInitialize() {
Symbolizer::GetOrInit();
}
} // namespace __sanitizer
#endif // _WIN32

View File

@ -370,6 +370,8 @@ void Initialize(ThreadState *thr) {
#endif
ctx->initialized = true;
Symbolizer::LateInitialize();
if (flags()->stop_on_start) {
Printf("ThreadSanitizer is suspended at startup (pid %d)."
" Call __tsan_resume().\n",