diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -895,6 +895,10 @@ Put crash-report files in +.. envvar:: CLANG_CRASH_DIAGNOSTICS_DIR= + +Put crash-report files in , with a lower precedence than :option:`-fcrash-diagnostics-dir=` + .. option:: -fcrash-diagnostics=, -fcrash-diagnostics (equivalent to -fcrash-diagnostics=compiler) Set level of crash diagnostic reporting, (option: off, compiler, all) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -134,6 +134,9 @@ Non-comprehensive list of changes in this release ------------------------------------------------- +- It's now possible to set the crash diagnostics directory through + the environment variable ``CLANG_CRASH_DIAGNOSTICS_DIR``. + The ``-fcrash-diagnostics-dir`` flag takes precedence. New Compiler Flags ------------------ diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -687,6 +687,11 @@ Specify where to write the crash diagnostics files; defaults to the usual location for temporary files. +.. envvar:: CLANG_CRASH_DIAGNOSTICS_DIR + + Like :option:`-fcrash-diagnostics-dir=`, specifies where to write the + crash diagnostics files, but with lower precedence than the option. + Clang is also capable of generating preprocessed source file(s) and associated run script(s) even without a crash. This is specially useful when trying to generate a reproducer for warnings or errors while using modules. diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5417,15 +5417,18 @@ StringRef BoundArch) const { SmallString<128> TmpName; Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir); - if (CCGenDiagnostics && A) { - SmallString<128> CrashDirectory(A->getValue()); - if (!getVFS().exists(CrashDirectory)) - llvm::sys::fs::create_directories(CrashDirectory); - llvm::sys::path::append(CrashDirectory, Prefix); + Optional CrashDirectory = + CCGenDiagnostics && A + ? std::string(A->getValue()) + : llvm::sys::Process::GetEnv("CLANG_CRASH_DIAGNOSTICS_DIR"); + if (CrashDirectory) { + if (!getVFS().exists(*CrashDirectory)) + llvm::sys::fs::create_directories(*CrashDirectory); + SmallString<128> Path(*CrashDirectory); + llvm::sys::path::append(Path, Prefix); const char *Middle = !Suffix.empty() ? "-%%%%%%." : "-%%%%%%"; - std::error_code EC = llvm::sys::fs::createUniqueFile( - CrashDirectory + Middle + Suffix, TmpName); - if (EC) { + if (std::error_code EC = + llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) { Diag(clang::diag::err_unable_to_make_temp) << EC.message(); return ""; } diff --git a/clang/test/Driver/crash-diagnostics-dir-3.c b/clang/test/Driver/crash-diagnostics-dir-3.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/crash-diagnostics-dir-3.c @@ -0,0 +1,5 @@ +// RUN: rm -rf %t +// RUN: not env CLANG_CRASH_DIAGNOSTICS_DIR=%t %clang -c %s -o - 2>&1 | FileCheck %s +#pragma clang __debug parser_crash +// CHECK: Preprocessed source(s) and associated run script(s) are located at: +// CHECK: diagnostic msg: {{.*}}{{/|\\}}crash-diagnostics-dir-3.c.tmp{{(/|\\).*}}.c diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -369,10 +369,12 @@ artifact_paths: - "**/test-results.xml" - "**/*.abilist" + - "**/crash_diagnostics/*" env: CC: "clang-${LLVM_HEAD_VERSION}" CXX: "clang++-${LLVM_HEAD_VERSION}" LLVM_SYMBOLIZER_PATH: "/usr/bin/llvm-symbolizer-${LLVM_HEAD_VERSION}" + CLANG_CRASH_DIAGNOSTICS_DIR: "crash_diagnostics" agents: queue: "libcxx-builders" os: "linux"