Made the ClangASTImporter into a shared pointer, eliminating a race condition.

It used to be a unique pointer, and there could be a case where ClangASTSource
held onto a copy of the pointer but Target::Destroy destroyed the unique pointer
in the mean time.

I also ensured that there is a validity check on the target (which confirms that
a ClangASTImporter can be generated) before the target's shared pointer is
copied into ClangASTSource.

This race condition caused a crash if Target::Destroy was called and then later
the target objecct was deleted.

llvm-svn: 252665
This commit is contained in:
Sean Callanan 2015-11-10 22:54:42 +00:00
parent 1ff9c63204
commit a3444ffcdd
7 changed files with 60 additions and 63 deletions

View File

@ -1287,7 +1287,7 @@ public:
ClangASTContext *
GetScratchClangASTContext(bool create_on_demand=true);
ClangASTImporter *
lldb::ClangASTImporterSP
GetClangASTImporter();
//----------------------------------------------------------------------
@ -1568,7 +1568,7 @@ protected:
typedef std::map<lldb::LanguageType, lldb::REPLSP> REPLMap;
REPLMap m_repl_map;
lldb::ClangASTImporterUP m_ast_importer_ap;
lldb::ClangASTImporterSP m_ast_importer_sp;
lldb::ClangModulesDeclVendorUP m_clang_modules_decl_vendor_ap;
lldb::SourceManagerUP m_source_manager_ap;

View File

@ -310,7 +310,7 @@ namespace lldb {
typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
typedef std::unique_ptr<lldb_private::ClangASTContext> ClangASTContextUP;
typedef std::unique_ptr<lldb_private::ClangASTImporter> ClangASTImporterUP;
typedef std::shared_ptr<lldb_private::ClangASTImporter> ClangASTImporterSP;
typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP;
typedef std::unique_ptr<lldb_private::ClangPersistentVariables> ClangPersistentVariablesUP;
typedef std::shared_ptr<lldb_private::UserExpression> UserExpressionSP;

View File

@ -57,7 +57,7 @@ namespace {
ClangASTSource::~ClangASTSource()
{
m_ast_importer->ForgetDestination(m_ast_context);
m_ast_importer_sp->ForgetDestination(m_ast_context);
// We are in the process of destruction, don't create clang ast context on demand
// by passing false to Target::GetScratchClangASTContext(create_on_demand).
@ -72,7 +72,7 @@ ClangASTSource::~ClangASTSource()
return;
if (m_ast_context != scratch_ast_context)
m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context);
m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
}
void
@ -221,7 +221,7 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
m_active_lexical_decls.insert(tag_decl);
ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
if (!m_ast_importer->CompleteTagDecl (tag_decl))
if (!m_ast_importer_sp->CompleteTagDecl (tag_decl))
{
// We couldn't complete the type. Maybe there's a definition
// somewhere else that can be completed.
@ -235,7 +235,7 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
@ -283,7 +283,7 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
found = true;
}
}
@ -322,7 +322,7 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
found = true;
}
}
@ -354,7 +354,7 @@ ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
if (m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx))
if (m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx))
{
if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
{
@ -362,12 +362,12 @@ ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
{
m_ast_importer->SetDeclOrigin(interface_decl, original_iface_decl);
m_ast_importer_sp->SetDeclOrigin(interface_decl, original_iface_decl);
}
}
}
m_ast_importer->CompleteObjCInterfaceDecl (interface_decl);
m_ast_importer_sp->CompleteObjCInterfaceDecl (interface_decl);
if (interface_decl->getSuperClass() &&
interface_decl->getSuperClass() != interface_decl)
@ -462,7 +462,7 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
return;
if (log)
@ -482,7 +482,7 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
original_decl = complete_iface_decl;
original_ctx = &complete_iface_decl->getASTContext();
m_ast_importer->SetDeclOrigin(context_decl, original_iface_decl);
m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl);
}
}
@ -516,7 +516,7 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
}
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
if (!copied_decl)
continue;
@ -525,7 +525,7 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
{
QualType copied_field_type = copied_field->getType();
m_ast_importer->RequireCompleteType(copied_field_type);
m_ast_importer_sp->RequireCompleteType(copied_field_type);
}
DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context);
@ -581,7 +581,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
@ -813,7 +813,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
llvm::isa<clang::EnumConstantDecl>(decl_from_modules))
{
clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
if (!copied_named_decl)
@ -871,7 +871,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
name.GetCString());
}
clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decls[0]->getASTContext(), decls[0]);
clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decls[0]->getASTContext(), decls[0]);
clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
if (!copied_named_decl)
@ -1066,7 +1066,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
if (!original_decl)
break;
@ -1077,7 +1077,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
context,
original_interface_decl,
m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
"at origin"))
return; // found it, no need to look any further
} while (0);
@ -1224,7 +1224,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
if (found_interface_decl->getName() == interface_decl->getName())
{
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
if (!copied_decl)
continue;
@ -1272,7 +1272,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
context,
complete_interface_decl,
m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
"in debug info");
return;
@ -1305,7 +1305,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
context,
interface_decl_from_modules,
m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
"in modules"))
return;
}
@ -1351,7 +1351,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
context,
runtime_interface_decl,
m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
"in runtime");
}
while(0);
@ -1423,7 +1423,7 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
unsigned int current_id = invocation_id++;
DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer_sp.get()));
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
@ -1436,7 +1436,7 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
context,
*m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
origin_iface_decl))
return;
@ -1471,7 +1471,7 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
context,
*m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
complete_iface_decl);
return;
@ -1511,7 +1511,7 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
context,
*m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
interface_decl_from_modules))
return;
}
@ -1561,7 +1561,7 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
context,
*m_ast_context,
m_ast_importer,
m_ast_importer_sp.get(),
interface_decl_from_runtime))
return;
}
@ -1664,7 +1664,7 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6
record->getNameAsString().c_str());
DeclFromParser <const RecordDecl> parser_record(record);
DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer_sp.get()));
if (origin_record.IsInvalid())
return false;
@ -1706,9 +1706,9 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6
return false;
}
if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) ||
!ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
!ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer_sp.get(), parser_ast_context) ||
!ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer_sp.get(), parser_ast_context) ||
!ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer_sp.get(), parser_ast_context))
return false;
size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
@ -1870,7 +1870,7 @@ ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::Name
if (!src_namespace_decl)
return nullptr;
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
if (!copied_decl)
return nullptr;
@ -1882,7 +1882,7 @@ ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::Name
context.m_decls.push_back(copied_namespace_decl);
m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
return dyn_cast<NamespaceDecl>(copied_decl);
}
@ -1898,7 +1898,7 @@ ClangASTSource::GuardedCopyType (const CompilerType &src_type)
SetImportInProgress(true);
QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_ast->getASTContext(), ClangASTContext::GetQualType(src_type));
QualType copied_qual_type = m_ast_importer_sp->CopyType (m_ast_context, src_ast->getASTContext(), ClangASTContext::GetQualType(src_type));
SetImportInProgress(false);

View File

@ -54,7 +54,7 @@ public:
m_active_lexical_decls (),
m_active_lookups ()
{
m_ast_importer = m_target->GetClangASTImporter();
m_ast_importer_sp = m_target->GetClangASTImporter();
}
//------------------------------------------------------------------
@ -77,7 +77,7 @@ public:
void InstallASTContext (clang::ASTContext *ast_context)
{
m_ast_context = ast_context;
m_ast_importer->InstallMapCompleter(ast_context, *this);
m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
}
//
@ -405,7 +405,7 @@ protected:
const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
ClangASTImporter *m_ast_importer; ///< The target's AST importer.
lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
std::set<const clang::Decl *> m_active_lexical_decls;
std::set<const char *> m_active_lookups;
};

View File

@ -215,9 +215,9 @@ ClangExpressionDeclMap::AddPersistentVariable
ClangASTContext *context(target->GetScratchClangASTContext());
TypeFromUser user_type(m_ast_importer->DeportType(context->getASTContext(),
ast->getASTContext(),
parser_type.GetOpaqueQualType()),
TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
ast->getASTContext(),
parser_type.GetOpaqueQualType()),
context);
uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(user_type,
@ -258,9 +258,9 @@ ClangExpressionDeclMap::AddPersistentVariable
ClangASTContext *context(target->GetScratchClangASTContext());
TypeFromUser user_type(m_ast_importer->DeportType(context->getASTContext(),
ast->getASTContext(),
parser_type.GetOpaqueQualType()),
TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
ast->getASTContext(),
parser_type.GetOpaqueQualType()),
context);
if (!user_type.GetOpaqueQualType())
@ -971,7 +971,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
@ -1291,7 +1291,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
if (!ptype_type_decl)
break;
Decl *parser_ptype_decl = m_ast_importer->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl);
Decl *parser_ptype_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl);
if (!parser_ptype_decl)
break;
@ -1473,7 +1473,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
{
if (llvm::isa<clang::FunctionDecl>(decl))
{
clang::NamedDecl *copied_decl = llvm::cast<FunctionDecl>(m_ast_importer->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
clang::NamedDecl *copied_decl = llvm::cast<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
context.AddNamedDecl(copied_decl);
context.m_found.function_with_type_info = true;
}
@ -1524,7 +1524,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
name.GetCString());
}
clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::FunctionDecl *copied_function_decl = copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) : nullptr;
if (!copied_function_decl)
@ -1556,7 +1556,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
name.GetCString());
}
clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr;
if (!copied_var_decl)
@ -1929,7 +1929,7 @@ ClangExpressionDeclMap::ResolveUnknownTypes()
QualType var_type = var_decl->getType();
TypeFromParser parser_type(var_type.getAsOpaquePtr(), ClangASTContext::GetASTContext(&var_decl->getASTContext()));
lldb::opaque_compiler_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context->getASTContext(), &var_decl->getASTContext(), var_type.getAsOpaquePtr());
lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(scratch_ast_context->getASTContext(), &var_decl->getASTContext(), var_type.getAsOpaquePtr());
if (!copied_type)
{

View File

@ -410,7 +410,7 @@ ClangASTContext::CreateInstance (lldb::LanguageType language,
}
return ast_sp;
}
else if (target)
else if (target && target->IsValid())
{
std::shared_ptr<ClangASTContextForExpressions> ast_sp(new ClangASTContextForExpressions(*target));
if (ast_sp)

View File

@ -83,7 +83,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
m_process_sp (),
m_search_filter_sp (),
m_image_search_paths (ImageSearchPathsChanged, this),
m_ast_importer_ap (),
m_ast_importer_sp (),
m_source_manager_ap(),
m_stop_hooks (),
m_stop_hook_next_id (0),
@ -1178,7 +1178,7 @@ Target::ClearModules(bool delete_locations)
m_section_load_history.Clear();
m_images.Clear();
m_scratch_type_system_map.Clear();
m_ast_importer_ap.reset();
m_ast_importer_sp.reset();
}
void
@ -2107,21 +2107,18 @@ Target::GetScratchClangASTContext(bool create_on_demand)
return nullptr;
}
ClangASTImporter *
ClangASTImporterSP
Target::GetClangASTImporter()
{
if (m_valid)
{
ClangASTImporter *ast_importer = m_ast_importer_ap.get();
if (!ast_importer)
if (!m_ast_importer_sp)
{
ast_importer = new ClangASTImporter();
m_ast_importer_ap.reset(ast_importer);
m_ast_importer_sp.reset(new ClangASTImporter());
}
return ast_importer;
return m_ast_importer_sp;
}
return nullptr;
return ClangASTImporterSP();
}
void