From: Ted Kremenek Date: Tue, 22 Mar 2011 01:15:24 +0000 (+0000) Subject: Rework crash recovery cleanup in ASTUnit and CIndex to recover more memory during... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=25a11e1c5fad62dbad25a265e334720157e3fbc1;p=clang Rework crash recovery cleanup in ASTUnit and CIndex to recover more memory during a Sema crash (we have just a handful of leaks left) and to use the simplified cleanup registration API. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128059 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 4a3b5f9f62..3a2b0afed8 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -503,9 +503,11 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, llvm::OwningPtr AST(new ASTUnit(true)); // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar - ASTUnitCleanup(llvm::CrashRecoveryContextCleanup:: - create(AST.get())); + llvm::CrashRecoveryContextCleanupRegistrar + ASTUnitCleanup(AST.get()); + llvm::CrashRecoveryContextCleanupRegistrar > + DiagCleanup(Diags.getPtr()); ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); @@ -850,9 +852,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { llvm::OwningPtr Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar - CICleanup(llvm::CrashRecoveryContextCleanup:: - create(Clang.get())); + llvm::CrashRecoveryContextCleanupRegistrar + CICleanup(Clang.get()); Clang->setInvocation(&*Invocation); OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; @@ -945,8 +946,13 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { PreprocessorOpts.PrecompiledPreambleBytes.second = false; } - llvm::OwningPtr Act; - Act.reset(new TopLevelDeclTrackerAction(*this)); + llvm::OwningPtr Act( + new TopLevelDeclTrackerAction(*this)); + + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar + ActCleanup(Act.get()); + if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, Clang->getFrontendOpts().Inputs[0].first)) goto error; @@ -1334,9 +1340,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( llvm::OwningPtr Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar - CICleanup(llvm::CrashRecoveryContextCleanup:: - create(Clang.get())); + llvm::CrashRecoveryContextCleanupRegistrar + CICleanup(Clang.get()); Clang->setInvocation(&PreambleInvocation); OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; @@ -1570,6 +1575,10 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { SimpleTimer ParsingTimer(WantTiming); ParsingTimer.setOutput("Parsing " + getMainFileName()); + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar + MemBufferCleanup(OverrideMainBuffer); + return Parse(OverrideMainBuffer); } @@ -1592,9 +1601,11 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, AST->Invocation = CI; // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar - ASTUnitCleanup(llvm::CrashRecoveryContextCleanup:: - create(AST.get())); + llvm::CrashRecoveryContextCleanupRegistrar + ASTUnitCleanup(AST.get()); + llvm::CrashRecoveryContextCleanupRegistrar > + DiagCleanup(Diags.getPtr()); return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); } @@ -1621,13 +1632,19 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, ArgBegin); } - llvm::SmallVector Args; - Args.push_back(""); // FIXME: Remove dummy argument. - Args.insert(Args.end(), ArgBegin, ArgEnd); + llvm::OwningPtr > + Args(new std::vector); + + // Recover resources if we crash before exiting this function. + llvm::CrashRecoveryContextCleanupRegistrar< + std::vector > CleanupArgs(Args.get()); + + Args->push_back(""); // FIXME: Remove dummy argument. + Args->insert(Args->end(), ArgBegin, ArgEnd); // FIXME: Find a cleaner way to force the driver into restricted modes. We // also want to force it to use clang. - Args.push_back("-fsyntax-only"); + Args->push_back("-fsyntax-only"); llvm::SmallVector StoredDiagnostics; @@ -1645,7 +1662,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, TheDriver.setCheckInputsExist(false); llvm::OwningPtr C( - TheDriver.BuildCompilation(Args.size(), Args.data())); + TheDriver.BuildCompilation(Args->size(), Args->data())); // Just print the cc1 options if -### was present. if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) { @@ -1724,9 +1741,14 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, AST->Invocation = CI; // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar - ASTUnitCleanup(llvm::CrashRecoveryContextCleanup:: - create(AST.get())); + llvm::CrashRecoveryContextCleanupRegistrar + ASTUnitCleanup(AST.get()); + llvm::CrashRecoveryContextCleanupRegistrar > + CICleanup(CI.getPtr()); + llvm::CrashRecoveryContextCleanupRegistrar > + DiagCleanup(Diags.getPtr()); return AST->LoadFromCompilerInvocation(PrecompilePreamble) ? 0 : AST.take(); } @@ -2056,9 +2078,8 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, llvm::OwningPtr Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar - CICleanup(llvm::CrashRecoveryContextCleanup:: - create(Clang.get())); + llvm::CrashRecoveryContextCleanupRegistrar + CICleanup(Clang.get()); Clang->setInvocation(&*CCInvocation); OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 500b1a51af..ddde439806 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2390,21 +2390,37 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { // Configure the diagnostics. DiagnosticOptions DiagOpts; - llvm::IntrusiveRefCntPtr Diags; - Diags = CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, - command_line_args); + llvm::IntrusiveRefCntPtr + Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, + command_line_args)); + + // Recover resources if we crash before exiting this function. + llvm::CrashRecoveryContextCleanupRegistrar > + DiagCleanup(Diags.getPtr()); + + llvm::OwningPtr > + RemappedFiles(new std::vector()); + + // Recover resources if we crash before exiting this function. + llvm::CrashRecoveryContextCleanupRegistrar< + std::vector > RemappedCleanup(RemappedFiles.get()); - llvm::SmallVector RemappedFiles; for (unsigned I = 0; I != num_unsaved_files; ++I) { llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); const llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, - Buffer)); + RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename, + Buffer)); } - llvm::SmallVector Args; - + llvm::OwningPtr > + Args(new std::vector()); + + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar > + ArgsCleanup(Args.get()); + // Since the Clang C library is primarily used by batch tools dealing with // (often very broken) source code, where spell-checking can have a // significant negative impact on performance (particularly when @@ -2419,10 +2435,10 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { } } if (!FoundSpellCheckingArgument) - Args.push_back("-fno-spell-checking"); + Args->push_back("-fno-spell-checking"); - Args.insert(Args.end(), command_line_args, - command_line_args + num_command_line_args); + Args->insert(Args->end(), command_line_args, + command_line_args + num_command_line_args); // The 'source_filename' argument is optional. If the caller does not // specify it then it is assumed that the source file is specified @@ -2430,23 +2446,23 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { // Put the source file after command_line_args otherwise if '-x' flag is // present it will be unused. if (source_filename) - Args.push_back(source_filename); + Args->push_back(source_filename); // Do we need the detailed preprocessing record? if (options & CXTranslationUnit_DetailedPreprocessingRecord) { - Args.push_back("-Xclang"); - Args.push_back("-detailed-preprocessing-record"); + Args->push_back("-Xclang"); + Args->push_back("-detailed-preprocessing-record"); } unsigned NumErrors = Diags->getClient()->getNumErrors(); llvm::OwningPtr Unit( - ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), + ASTUnit::LoadFromCommandLine(Args->data(), Args->data() + Args->size(), Diags, CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(), /*CaptureDiagnostics=*/true, - RemappedFiles.data(), - RemappedFiles.size(), + RemappedFiles->data(), + RemappedFiles->size(), /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, CompleteTranslationUnit, @@ -2569,16 +2585,22 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) { ASTUnit *CXXUnit = static_cast(TU->TUData); ASTUnit::ConcurrencyCheck Check(*CXXUnit); - llvm::SmallVector RemappedFiles; + llvm::OwningPtr > + RemappedFiles(new std::vector()); + + // Recover resources if we crash before exiting this function. + llvm::CrashRecoveryContextCleanupRegistrar< + std::vector > RemappedCleanup(RemappedFiles.get()); + for (unsigned I = 0; I != num_unsaved_files; ++I) { llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); const llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, - Buffer)); + RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename, + Buffer)); } - if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size())) + if (!CXXUnit->Reparse(RemappedFiles->data(), RemappedFiles->size())) RTUI->result = 0; }