Author: Oliver Hunt Date: 2020-07-09T20:27:33-07:00 New Revision: 00c9a504aeed2603bd8bc9b89d753534e929c8e8
URL: https://github.com/llvm/llvm-project/commit/00c9a504aeed2603bd8bc9b89d753534e929c8e8 DIFF: https://github.com/llvm/llvm-project/commit/00c9a504aeed2603bd8bc9b89d753534e929c8e8.diff LOG: CrashTracer: clang at clang: llvm::BitstreamWriter::ExitBlock Add a guard for re-entering an SDiagsWriter's HandleDiagnostics method after we've started finalizing. This is a generic catch all for unexpected fatal errors so we don't recursive crash inside the generic llvm error handler. We also add logic to handle the actual error case in llvm::~raw_fd_ostream caused by failing to clear errors before it is destroyed. <rdar://problem/63335596> Added: Modified: clang/include/clang/Basic/DiagnosticFrontendKinds.td clang/lib/Frontend/SerializedDiagnosticPrinter.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 83c13e0dbbe0..ceb24bce5978 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -119,6 +119,9 @@ def warn_fe_serialized_diag_merge_failure : Warning< def warn_fe_serialized_diag_failure : Warning< "unable to open file %0 for serializing diagnostics (%1)">, InGroup<SerializedDiagnostics>; +def warn_fe_serialized_diag_failure_during_finalisation : Warning< + "Received warning after diagnostic serialization teardown was underway: %0">, + InGroup<SerializedDiagnostics>; def err_verify_missing_line : Error< "missing or invalid line number following '@' in expected %0">; diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index e3ca8fdec393..462aeda6e027 100644 --- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -239,6 +239,9 @@ class SDiagsWriter : public DiagnosticConsumer { /// generated from child processes. bool MergeChildRecords; + /// Whether we've started finishing and tearing down this instance. + bool IsFinishing = false; + /// State that is shared among the various clones of this diagnostic /// consumer. struct SharedState { @@ -568,6 +571,17 @@ unsigned SDiagsWriter::getEmitDiagnosticFlag(StringRef FlagName) { void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { + assert(!IsFinishing && + "Received a diagnostic after we've already started teardown."); + if (IsFinishing) { + SmallString<256> diagnostic; + Info.FormatDiagnostic(diagnostic); + getMetaDiags()->Report( + diag::warn_fe_serialized_diag_failure_during_finalisation) + << diagnostic; + return; + } + // Enter the block for a non-note diagnostic immediately, rather than waiting // for beginDiagnostic, in case associated notes are emitted before we get // there. @@ -761,6 +775,9 @@ void SDiagsWriter::RemoveOldDiagnostics() { } void SDiagsWriter::finish() { + assert(!IsFinishing); + IsFinishing = true; + // The original instance is responsible for writing the file. if (!OriginalInstance) return; @@ -786,12 +803,20 @@ void SDiagsWriter::finish() { if (EC) { getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) << State->OutputFile << EC.message(); + OS->clear_error(); return; } // Write the generated bitstream to "Out". OS->write((char *)&State->Buffer.front(), State->Buffer.size()); OS->flush(); + + assert(!OS->has_error()); + if (OS->has_error()) { + getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) + << State->OutputFile << OS->error().message(); + OS->clear_error(); + } } std::error_code SDiagsMerger::visitStartOfDiagnostic() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits