Skip to content

Commit

Permalink
[TypeSystem] Guard the global ASTSourceMap with a mutex
Browse files Browse the repository at this point in the history
s_source_map in ClangExternalASTSourceCommon.cpp is unguarded 
and therefore can break in multithreaded conditions. This can 
cause crashes in particular if multiple targets are being set
up at once.

This patch wraps s_source_map in a function that ensures 
exclusivity, and makes every user of it use that function
instead.

<rdar://problem/33429774> lldb crashes after "resume_off"

Differential Revision: https://reviews.llvm.org/D35083

llvm-svn: 308993
  • Loading branch information
scallanan committed Jul 25, 2017
1 parent dafea67 commit afc70ab
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions lldb/source/Symbol/ClangExternalASTSourceCommon.cpp
Expand Up @@ -10,6 +10,8 @@
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Utility/Stream.h"

#include <mutex>

using namespace lldb_private;

uint64_t g_TotalSizeOfMetadata = 0;
Expand All @@ -18,15 +20,19 @@ typedef llvm::DenseMap<clang::ExternalASTSource *,
ClangExternalASTSourceCommon *>
ASTSourceMap;

static ASTSourceMap &GetSourceMap() {
static ASTSourceMap &GetSourceMap(std::unique_lock<std::mutex> &guard) {
// Intentionally leaked to avoid problems with global destructors.
static ASTSourceMap *s_source_map = new ASTSourceMap;
static std::mutex s_mutex;
std::unique_lock<std::mutex> locked_guard(s_mutex);
guard.swap(locked_guard);
return *s_source_map;
}

ClangExternalASTSourceCommon *
ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source) {
ASTSourceMap &source_map = GetSourceMap();
std::unique_lock<std::mutex> guard;
ASTSourceMap &source_map = GetSourceMap(guard);

ASTSourceMap::iterator iter = source_map.find(source);

Expand All @@ -40,11 +46,13 @@ ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source) {
ClangExternalASTSourceCommon::ClangExternalASTSourceCommon()
: clang::ExternalASTSource() {
g_TotalSizeOfMetadata += m_metadata.size();
GetSourceMap()[this] = this;
std::unique_lock<std::mutex> guard;
GetSourceMap(guard)[this] = this;
}

ClangExternalASTSourceCommon::~ClangExternalASTSourceCommon() {
GetSourceMap().erase(this);
std::unique_lock<std::mutex> guard;
GetSourceMap(guard).erase(this);
g_TotalSizeOfMetadata -= m_metadata.size();
}

Expand Down

0 comments on commit afc70ab

Please sign in to comment.