forked from OSchip/llvm-project
[libclang] For clang_saveTranslationUnit, if the AST to save has invalid nodes
due to compiler errors, use a crash recovery thread to do the AST writing for protection. llvm-svn: 153560
This commit is contained in:
parent
f981060503
commit
9d3ffffec0
|
@ -2648,15 +2648,62 @@ unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
|
||||||
return CXSaveTranslationUnit_None;
|
return CXSaveTranslationUnit_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct SaveTranslationUnitInfo {
|
||||||
|
CXTranslationUnit TU;
|
||||||
|
const char *FileName;
|
||||||
|
unsigned options;
|
||||||
|
CXSaveError result;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clang_saveTranslationUnit_Impl(void *UserData) {
|
||||||
|
SaveTranslationUnitInfo *STUI =
|
||||||
|
static_cast<SaveTranslationUnitInfo*>(UserData);
|
||||||
|
|
||||||
|
STUI->result = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName);
|
||||||
|
}
|
||||||
|
|
||||||
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
|
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
|
||||||
unsigned options) {
|
unsigned options) {
|
||||||
if (!TU)
|
if (!TU)
|
||||||
return CXSaveError_InvalidTU;
|
return CXSaveError_InvalidTU;
|
||||||
|
|
||||||
CXSaveError result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
|
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||||
|
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||||
|
|
||||||
|
SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
|
||||||
|
|
||||||
|
if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
|
||||||
|
getenv("LIBCLANG_NOTHREADS")) {
|
||||||
|
clang_saveTranslationUnit_Impl(&STUI);
|
||||||
|
|
||||||
if (getenv("LIBCLANG_RESOURCE_USAGE"))
|
if (getenv("LIBCLANG_RESOURCE_USAGE"))
|
||||||
PrintLibclangResourceUsage(TU);
|
PrintLibclangResourceUsage(TU);
|
||||||
return result;
|
|
||||||
|
return STUI.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have an AST that has invalid nodes due to compiler errors.
|
||||||
|
// Use a crash recovery thread for protection.
|
||||||
|
|
||||||
|
llvm::CrashRecoveryContext CRC;
|
||||||
|
|
||||||
|
if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
|
||||||
|
fprintf(stderr, "libclang: crash detected during AST saving: {\n");
|
||||||
|
fprintf(stderr, " 'filename' : '%s'\n", FileName);
|
||||||
|
fprintf(stderr, " 'options' : %d,\n", options);
|
||||||
|
fprintf(stderr, "}\n");
|
||||||
|
|
||||||
|
return CXSaveError_Unknown;
|
||||||
|
|
||||||
|
} else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
|
||||||
|
PrintLibclangResourceUsage(TU);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STUI.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
|
void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
|
||||||
|
|
Loading…
Reference in New Issue