From: Bob Haarman Date: Mon, 9 Jul 2018 21:07:20 +0000 (+0000) Subject: Added -fcrash-diagnostics-dir flag X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=15685126aca86d46c25fcc0964173377adc1cc3d;p=clang Added -fcrash-diagnostics-dir flag Summary: New flag causes crash reports to be written in the specified directory rather than the temp directory. Patch by Chijioke Kamanu. Reviewers: hans, inglorion, rnk Reviewed By: hans Subscribers: zturner, hiraditya, llvm-commits, cfe-commits Differential Revision: https://reviews.llvm.org/D48601 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336604 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 496cc12aa3..f958999f1c 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -798,6 +798,7 @@ def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit="> Group; def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group, Flags<[NoArgumentUnused]>, HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">; +def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group, Flags<[NoArgumentUnused]>; def fcreate_profile : Flag<["-"], "fcreate-profile">, Group; def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group, HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 1fd7a6d718..9e92f64f66 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1291,12 +1291,13 @@ void Driver::generateCompilationDiagnostics( // Assume associated files are based off of the first temporary file. CrashReportInfo CrashInfo(TempFiles[0], VFS); - std::string Script = CrashInfo.Filename.rsplit('.').first.str() + ".sh"; + llvm::SmallString<128> Script(CrashInfo.Filename); + llvm::sys::path::replace_extension(Script, "sh"); std::error_code EC; llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew); if (EC) { Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating run script: " + Script + " " + EC.message(); + << "Error generating run script: " << Script << " " << EC.message(); } else { ScriptOS << "# Crash reproducer for " << getClangFullVersion() << "\n" << "# Driver args: "; @@ -1308,7 +1309,7 @@ void Driver::generateCompilationDiagnostics( ScriptOS << "\n# Additional information: " << AdditionalInformation << "\n"; if (Report) - Report->TemporaryFiles.push_back(Script); + Report->TemporaryFiles.push_back(Script.str()); Diag(clang::diag::note_drv_command_failed_diag_msg) << Script; } @@ -4018,8 +4019,22 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, CCGenDiagnostics) { StringRef Name = llvm::sys::path::filename(BaseInput); std::pair Split = Name.split('.'); - std::string TmpName = GetTemporaryPath( - Split.first, types::getTypeTempSuffix(JA.getType(), IsCLMode())); + SmallString<128> TmpName; + const char *Suffix = types::getTypeTempSuffix(JA.getType(), IsCLMode()); + Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir); + if (CCGenDiagnostics && A) { + SmallString<128> CrashDirectory(A->getValue()); + llvm::sys::path::append(CrashDirectory, Split.first); + const char *Middle = Suffix ? "-%%%%%%." : "-%%%%%%"; + std::error_code EC = + llvm::sys::fs::createUniqueFile(CrashDirectory + Middle + Suffix, TmpName); + if (EC) { + Diag(clang::diag::err_unable_to_make_temp) << EC.message(); + return ""; + } + } else { + TmpName = GetTemporaryPath(Split.first, Suffix); + } return C.addTempFile(C.getArgs().MakeArgString(TmpName)); } diff --git a/test/Driver/crash-diagnostics-dir.c b/test/Driver/crash-diagnostics-dir.c new file mode 100644 index 0000000000..e922eac4be --- /dev/null +++ b/test/Driver/crash-diagnostics-dir.c @@ -0,0 +1,6 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: not %clang -fcrash-diagnostics-dir=%t -c %s 2>&1 | FileCheck %s +#pragma clang __debug parser_crash +// CHECK: Preprocessed source(s) and associated run script(s) are located at: +// CHECK: diagnostic msg: {{.*}}Output{{/|\\}}crash-diagnostics-dir.c.tmp{{(/|\\).*}}.c