[clang] 00c9a50 - CrashTracer: clang at clang: llvm::BitstreamWriter::ExitBlock

JF Bastien via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 9 20:29:47 PDT 2020


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() {


        


More information about the cfe-commits mailing list