[clang] Add -fcrash-diagnostics-tar for tarball of crash reproducer files#198838
Conversation
|
sorry, looks like this doesn't handle directories that we add in some crash dumps, let me fix that |
|
@llvm/pr-subscribers-clang-modules @llvm/pr-subscribers-clang-driver Author: Arthur Eubanks (aeubanks) ChangesMakes it easier to move around crash diagnostics. 3 Files Affected:
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 "
|
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
…iles Makes it easier to move around crash diagnostics.
| @@ -0,0 +1,17 @@ | |||
| // UNSUPPORTED: system-windows | |||
There was a problem hiding this comment.
Can we write some version of this test that works on Windows?
| } | ||
| } | ||
| Diag(clang::diag::note_drv_command_failed_diag_msg) | ||
| << (std::string("Crash reproducer tarball created at: ") + |
There was a problem hiding this comment.
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.
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
AaronBallman
left a comment
There was a problem hiding this comment.
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.
|
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 |
… crash reproducer files" (#201622) Reverts llvm/llvm-project#198838 Test failing at https://lab.llvm.org/buildbot/#/builders/190/builds/43494
… crash reproducer files" (#201622) Reverts llvm/llvm-project#198838 Test failing at https://lab.llvm.org/buildbot/#/builders/190/builds/43494
Makes it easier to move around crash diagnostics.