Skip to content

[clang] Add -fcrash-diagnostics-tar for tarball of crash reproducer files#198838

Merged
aeubanks merged 15 commits into
llvm:mainfrom
aeubanks:crash
Jun 4, 2026
Merged

[clang] Add -fcrash-diagnostics-tar for tarball of crash reproducer files#198838
aeubanks merged 15 commits into
llvm:mainfrom
aeubanks:crash

Conversation

@aeubanks
Copy link
Copy Markdown
Contributor

Makes it easier to move around crash diagnostics.

@aeubanks aeubanks requested review from AaronBallman and zmodem May 20, 2026 16:55
@aeubanks
Copy link
Copy Markdown
Contributor Author

sorry, looks like this doesn't handle directories that we add in some crash dumps, let me fix that

@llvmorg-github-actions llvmorg-github-actions Bot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels May 20, 2026
@llvmorg-github-actions
Copy link
Copy Markdown

llvmorg-github-actions Bot commented May 20, 2026

@llvm/pr-subscribers-clang-modules
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Arthur Eubanks (aeubanks)

Changes

Makes it easier to move around crash diagnostics.


Full diff: https://github.com/llvm/llvm-project/pull/198838.diff

3 Files Affected:

  • (modified) clang/include/clang/Options/Options.td (+4)
  • (modified) clang/lib/Driver/Driver.cpp (+30)
  • (added) clang/test/Driver/crash-diagnostics-tar.c (+16)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 753e3ac1b74a5..8ee8bb544535e 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -2177,6 +2177,10 @@ def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">,
   Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
   Visibility<[ClangOption, CLOption, DXCOption]>,
   HelpText<"Put crash-report files in <dir>">, MetaVarName<"<dir>">;
+def fcrash_diagnostics_tar : Joined<["-"], "fcrash-diagnostics-tar=">,
+  Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
+  Visibility<[ClangOption, CLOption, DXCOption]>,
+  HelpText<"Put crash-report tarball at <path>">, MetaVarName<"<path>">;
 def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
 defm cxx_exceptions: BoolFOption<"cxx-exceptions",
   LangOpts<"CXXExceptions">, DefaultFalse,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 4a968a4ce5cc0..82b238924735e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -98,12 +98,14 @@
 #include "llvm/Support/IOSandbox.h"
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/MD5.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/StringSaver.h"
+#include "llvm/Support/TarWriter.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Host.h"
@@ -2271,9 +2273,37 @@ void Driver::generateCompilationDiagnostics(
                << "\n";
     if (Report)
       Report->TemporaryFiles.push_back(std::string(Script));
+    TempFiles.push_back(std::string(Script));
+    ScriptOS.close();
     Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
   }
 
+  if (Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
+    StringRef CrashDiagnosticsTar = A->getValue();
+    Expected<std::unique_ptr<llvm::TarWriter>> TarOrErr =
+        llvm::TarWriter::create(CrashDiagnosticsTar,
+                                llvm::sys::path::stem(CrashDiagnosticsTar));
+    if (!TarOrErr) {
+      Diag(clang::diag::note_drv_command_failed_diag_msg)
+          << "Error creating reproducer tarball: "
+          << llvm::toString(TarOrErr.takeError());
+    } else {
+      std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
+      for (const std::string &TempFile : TempFiles) {
+        auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
+        if (BufferOrErr) {
+          Tar->append(llvm::sys::path::filename(TempFile),
+                      (*BufferOrErr)->getBuffer());
+        } else {
+          Diag(clang::diag::note_drv_command_failed_diag_msg)
+              << "Error reading file for tarball: " << TempFile;
+        }
+      }
+      Diag(clang::diag::note_drv_command_failed_diag_msg)
+          << "Crash reproducer tarball created at: " << CrashDiagnosticsTar;
+    }
+  }
+
   // On darwin, provide information about the .crash diagnostic report.
   if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
     SmallString<128> CrashDiagDir;
diff --git a/clang/test/Driver/crash-diagnostics-tar.c b/clang/test/Driver/crash-diagnostics-tar.c
new file mode 100644
index 0000000000000..232679bb8e67d
--- /dev/null
+++ b/clang/test/Driver/crash-diagnostics-tar.c
@@ -0,0 +1,16 @@
+// RUN: export LSAN_OPTIONS=detect_leaks=0
+// RUN: rm -rf %t
+// RUN: not %crash_opt %clang -fcrash-diagnostics-tar=%t -c %s -o - 2>&1 | FileCheck %s
+// RUN: rm -rf %t_dir
+// RUN: mkdir %t_dir
+// RUN: tar -xf %t -C %t_dir
+// RUN: FileCheck %s --check-prefix=SH < %t_dir/*/crash-diagnostics-tar-*.sh
+// RUN: FileCheck %s --check-prefix=C < %t_dir/*/crash-diagnostics-tar-*.c
+
+#pragma clang __debug parser_crash
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK: Crash reproducer tarball created at:
+
+// SH: # Crash reproducer for
+// C: # 1 "

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

🪟 Windows x64 Test Results

  • 55722 tests passed
  • 2617 tests skipped

✅ The build succeeded and all tests passed.

…iles

Makes it easier to move around crash diagnostics.
@@ -0,0 +1,17 @@
// UNSUPPORTED: system-windows
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we write some version of this test that works on Windows?

Comment thread clang/lib/Driver/Driver.cpp Outdated
}
}
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< (std::string("Crash reproducer tarball created at: ") +
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to modify the existing text, instead of adding an additional line? Presumably if someone creates a tar-file, we want them to attach just the tar-file to a bug report, not all the other files.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 22, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 22, 2026

🐧 Linux x64 Test Results

  • 118190 tests passed
  • 4795 tests skipped

✅ The build succeeded and all tests passed.

@llvmorg-github-actions llvmorg-github-actions Bot added the clang:modules C++20 modules and Clang Header Modules label May 25, 2026
Copy link
Copy Markdown
Contributor

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this! Please be sure to add a release note to clang/docs/ReleaseNotes.rst so users know about the feature. Perhaps we should document it more loudly in the user's manual too?

One thing I'd like to be sure we have test coverage for (and maybe we do, I could have missed it): what happens when the source is read from, say, stdin as opposed to a file we can tar? Similarly, we should have test coverage for an invalid file path to the tar file.

@aeubanks
Copy link
Copy Markdown
Contributor Author

aeubanks commented Jun 1, 2026

added tests for stdin/invalid tar path

added flag to release notes and user's manual

I think it'd be nice to turn this on by default and have it automatically dump a tarball in the same directory alongside the other crash reproducer files, but that should be a separate PR

Copy link
Copy Markdown
Contributor

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@aeubanks aeubanks merged commit e44d060 into llvm:main Jun 4, 2026
11 checks passed
@aeubanks aeubanks deleted the crash branch June 4, 2026 16:01
aeubanks added a commit that referenced this pull request Jun 4, 2026
…iles (#201643)

Makes it easier to move around crash diagnostics.

Reland of #198838 with crash-diagnostics-tar.c and
crash-report-crashfile.m fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants