From: Daniel Dunbar Date: Thu, 19 Aug 2010 23:44:10 +0000 (+0000) Subject: libclang: Execute clang_codeCompleteAt() inside a crash recovery context. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b1fd3458680bc9c8988dee8967e9c0709fef3945;p=clang libclang: Execute clang_codeCompleteAt() inside a crash recovery context. - Test case is disabled for now, because something isn't write with file remapping. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111581 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/Inputs/crash-recovery-code-complete-remap.c b/test/Index/Inputs/crash-recovery-code-complete-remap.c new file mode 100644 index 0000000000..50a86580a1 --- /dev/null +++ b/test/Index/Inputs/crash-recovery-code-complete-remap.c @@ -0,0 +1,12 @@ +// RUN: echo env CINDEXTEST_EDITING=1 \ +// RUN: not c-index-test -test-load-source-reparse 1 local \ +// RUN: -remap-file="%s;%S/Inputs/crash-recovery-code-complete-remap.c" \ +// RUN: %s 2> %t.err +// RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s +// CHECK-CODE-COMPLETE-CRASH: Unable to reparse translation unit +// +// XFAIL: win32 + +#warning parsing original file + +#pragma clang __debug crash diff --git a/test/Index/crash-recovery-code-complete.c b/test/Index/crash-recovery-code-complete.c new file mode 100644 index 0000000000..be834fb813 --- /dev/null +++ b/test/Index/crash-recovery-code-complete.c @@ -0,0 +1,11 @@ +// RUN: echo env CINDEXTEST_EDITING=1 \ +// RUN: not c-index-test -code-completion-at=%s:20:1 \ +// RUN: -remap-file="%s;%S/Inputs/crash-recovery-code-complete-remap.c" \ +// RUN: %s 2> %t.err +// RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s +// CHECK-CODE-COMPLETE-CRASH: Unable to reparse translation unit +// +// XFAIL: win32 +// XFAIL: * + +#warning parsing original file diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 8134971ab4..27d5ab25b8 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1221,7 +1221,7 @@ struct ParseTranslationUnitInfo { unsigned options; CXTranslationUnit result; }; -void clang_parseTranslationUnit_Impl(void *UserData) { +static void clang_parseTranslationUnit_Impl(void *UserData) { ParseTranslationUnitInfo *PTUI = static_cast(UserData); CXIndex CIdx = PTUI->CIdx; @@ -1491,7 +1491,7 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, llvm::CrashRecoveryContext CRC; if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) { - // FIXME: Find a way to report the crash. + fprintf(stderr, "libclang: crash detected during parsing"); return 0; } @@ -1532,7 +1532,7 @@ struct ReparseTranslationUnitInfo { unsigned options; int result; }; -void clang_reparseTranslationUnit_Impl(void *UserData) { +static void clang_reparseTranslationUnit_Impl(void *UserData) { ReparseTranslationUnitInfo *RTUI = static_cast(UserData); CXTranslationUnit TU = RTUI->TU; @@ -1567,7 +1567,7 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU, llvm::CrashRecoveryContext CRC; if (!CRC.RunSafely(clang_reparseTranslationUnit_Impl, &RTUI)) { - // FIXME: Find a way to report the crash. + fprintf(stderr, "libclang: crash detected during reparsing\n"); static_cast(TU)->setUnsafeToFree(true); return 1; } diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index 48bbe7d46b..53767c4467 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -22,6 +22,7 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" @@ -568,13 +569,27 @@ namespace { } extern "C" { -CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, - const char *complete_filename, - unsigned complete_line, - unsigned complete_column, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options) { +struct CodeCompleteAtInfo { + CXTranslationUnit TU; + const char *complete_filename; + unsigned complete_line; + unsigned complete_column; + struct CXUnsavedFile *unsaved_files; + unsigned num_unsaved_files; + unsigned options; + CXCodeCompleteResults *result; +}; +void clang_codeCompleteAt_Impl(void *UserData) { + CodeCompleteAtInfo *CCAI = static_cast(UserData); + CXTranslationUnit TU = CCAI->TU; + const char *complete_filename = CCAI->complete_filename; + unsigned complete_line = CCAI->complete_line; + unsigned complete_column = CCAI->complete_column; + struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files; + unsigned num_unsaved_files = CCAI->num_unsaved_files; + unsigned options = CCAI->options; + CCAI->result = 0; + #ifdef UDP_CODE_COMPLETION_LOGGER #ifdef UDP_CODE_COMPLETION_LOGGER_PORT const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime(); @@ -585,7 +600,7 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, ASTUnit *AST = static_cast(TU); if (!AST) - return 0; + return; // Perform the remapping of source files. llvm::SmallVector RemappedFiles; @@ -697,7 +712,27 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, } #endif #endif - return Results; + CCAI->result = Results; +} +CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, + const char *complete_filename, + unsigned complete_line, + unsigned complete_column, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, + unsigned options) { + CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line, + complete_column, unsaved_files, num_unsaved_files, + options, 0 }; + llvm::CrashRecoveryContext CRC; + + if (!CRC.RunSafely(clang_codeCompleteAt_Impl, &CCAI)) { + fprintf(stderr, "libclang: crash detected in code completion\n"); + static_cast(TU)->setUnsafeToFree(true); + return 0; + } + + return CCAI.result; } unsigned clang_defaultCodeCompleteOptions(void) {