From: Daniel Dunbar Date: Wed, 18 Aug 2010 18:43:17 +0000 (+0000) Subject: libclang: Put clang_parseTranslationUnit inside a crash recovery context. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=19ffd492a31a25fb691098bf79f317e5f3edf177;p=clang libclang: Put clang_parseTranslationUnit inside a crash recovery context. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111387 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/crash-recovery.c b/test/Index/crash-recovery.c new file mode 100644 index 0000000000..73920c2f33 --- /dev/null +++ b/test/Index/crash-recovery.c @@ -0,0 +1,7 @@ +// RUN: not c-index-test -test-load-source all %s 2> %t.err +// RUN: FileCheck < %t.err -check-prefix=CHECK-LOAD-SOURCE-CRASH %s +// CHECK-LOAD-SOURCE-CRASH: Unable to load translation unit +// +// XFAIL: win32 + +#pragma clang __debug crash diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index e0720e788a..829873e74f 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1209,16 +1209,31 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, unsaved_files, num_unsaved_files, CXTranslationUnit_DetailedPreprocessingRecord); } + +struct ParseTranslationUnitInfo { + CXIndex CIdx; + const char *source_filename; + const char **command_line_args; + int num_command_line_args; + struct CXUnsavedFile *unsaved_files; + unsigned num_unsaved_files; + unsigned options; + CXTranslationUnit result; +}; +void clang_parseTranslationUnit_Impl(void *UserData) { + ParseTranslationUnitInfo *PTUI = + static_cast(UserData); + CXIndex CIdx = PTUI->CIdx; + const char *source_filename = PTUI->source_filename; + const char **command_line_args = PTUI->command_line_args; + int num_command_line_args = PTUI->num_command_line_args; + struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; + unsigned num_unsaved_files = PTUI->num_unsaved_files; + unsigned options = PTUI->options; + PTUI->result = 0; -CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, - const char *source_filename, - const char **command_line_args, - int num_command_line_args, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options) { if (!CIdx) - return 0; + return; CIndexer *CXXIdx = static_cast(CIdx); @@ -1307,7 +1322,8 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, } } - return Unit.take(); + PTUI->result = Unit.take(); + return; } // Build up the arguments for invoking 'clang'. @@ -1343,7 +1359,7 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, std::vector TemporaryFiles; std::vector RemapArgs; if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) - return 0; + return; // The pointers into the elements of RemapArgs are stable because we // won't be adding anything to RemapArgs after this point. @@ -1459,7 +1475,26 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, TemporaryFiles[i].eraseFromDisk(); } - return ATU; + PTUI->result = ATU; +} +CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, + const char *source_filename, + const char **command_line_args, + int num_command_line_args, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, + unsigned options) { + ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, + num_command_line_args, unsaved_files, num_unsaved_files, + options, 0 }; + llvm::CrashRecoveryContext CRC; + + if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) { + // FIXME: Find a way to report the crash. + return 0; + } + + return PTUI.result; } unsigned clang_defaultSaveOptions(CXTranslationUnit TU) { @@ -1473,7 +1508,7 @@ int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, return static_cast(TU)->Save(FileName); } - + void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { if (CTUnit) delete static_cast(CTUnit);