https://github.com/xingxue-ibm updated https://github.com/llvm/llvm-project/pull/169340
>From b79cb89b75d0892a2e41fdf1fafa6e3b6a422280 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Fri, 21 Nov 2025 15:29:56 -0500 Subject: [PATCH 01/10] Don't install signal handler if the disposition of a signal is SIG_IGN, resignal after the signal handler handles a signal so the exit code of the compiler contains the signal number. --- .../unittests/ThreadCrashReporterTests.cpp | 12 +++++++++ clang/lib/Driver/Driver.cpp | 7 +++++ clang/tools/driver/driver.cpp | 18 ++++++++++++- llvm/lib/Support/CrashRecoveryContext.cpp | 6 ++++- llvm/lib/Support/Unix/Signals.inc | 27 ++++++++++++------- 5 files changed, 58 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp b/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp index 0eb8d472c6702..1c86fcbea4a4b 100644 --- a/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp +++ b/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp @@ -13,6 +13,17 @@ #include <csignal> #include <string> +// According to the POSIX specification, if the inherited disposition of a +// signal is the default action, the behavior of utilitys must be as if the +// default action had been taken. When the required default action is to +// terminate the process, such as for SIGUSR1, the utility may catch the +// signal, perform additional processing, restore the default disposition, +// and then re-signal itself. This causes the process to terminate as +// required. Because of this behavior, the crash-reporter test here is not +// suitable for Unix platforms. + +#ifndef LLVM_ON_UNIX + namespace clang { namespace clangd { @@ -76,3 +87,4 @@ TEST(ThreadCrashReporterTest, All) { } // namespace } // namespace clangd } // namespace clang +#endif // !LLVM_ON_UNIX diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a55c5033b57cf..e364d1efaeeec 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2316,7 +2316,14 @@ int Driver::ExecuteCompilation( if (!FailingCommand->getCreator().hasGoodDiagnostics() || CommandRes != 1) { // FIXME: See FIXME above regarding result code interpretation. +#if LLVM_ON_UNIX + // On Unix, signals are represented by return codes of 128 plus the + // signal number. Return code 255 is excluded because some tools, + // such as llvm-ifs, exit with code 255 (-1) on failure. + if (CommandRes > 128 && CommandRes != 255) +#else if (CommandRes < 0) +#endif Diag(clang::diag::err_drv_command_signalled) << FailingTool.getShortName(); else diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 490136961ebc6..a586494cdc8a9 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -55,6 +55,9 @@ #include <optional> #include <set> #include <system_error> +#if LLVM_ON_UNIX +#include <signal.h> +#endif using namespace clang; using namespace clang::driver; @@ -407,6 +410,7 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { Driver::CommandStatus CommandStatus = Driver::CommandStatus::Ok; // Pretend the first command failed if ReproStatus is Always. const Command *FailingCommand = nullptr; + int CommandRes = 0; if (!C->getJobs().empty()) FailingCommand = &*C->getJobs().begin(); if (C && !C->containsError()) { @@ -414,7 +418,7 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { Res = TheDriver.ExecuteCompilation(*C, FailingCommands); for (const auto &P : FailingCommands) { - int CommandRes = P.first; + CommandRes = P.first; FailingCommand = P.second; if (!Res) Res = CommandRes; @@ -471,6 +475,18 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { Res = 1; #endif +#if LLVM_ON_UNIX + // On Unix, signals are represented by return codes of 128 plus the signal + // number. If the return code indicates it was from a signal handler, raise + // the signal so that the exit code includes the signal number, as required + // by POSIX. Return code 255 is excluded because some tools, such as + // llvm-ifs, exit with code 255 (-1) on failure. + if (CommandRes > 128 && CommandRes != 255) { + llvm::sys::unregisterHandlers(); + raise(CommandRes - 128); + } +#endif + // If we have multiple failing commands, we return the result of the first // failing command. return Res; diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index 1ba0c2383daec..c6bfa4d0245da 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -398,7 +398,11 @@ static void installExceptionOrSignalHandlers() { sigemptyset(&Handler.sa_mask); for (unsigned i = 0; i != NumSignals; ++i) { - sigaction(Signals[i], &Handler, &PrevActions[i]); + struct sigaction act; + sigaction(Signals[i], NULL, &act); + // Don't install signal handler if the disposition of a signal is SIG_IGN. + if (act.sa_handler != SIG_IGN) + sigaction(Signals[i], &Handler, &PrevActions[i]); } } diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index 56ad4fc504153..35ac441d73be8 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -327,8 +327,12 @@ static void RegisterHandlers() { // Not signal-safe. } sigemptyset(&NewHandler.sa_mask); - // Install the new handler, save the old one in RegisteredSignalInfo. - sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA); + // Install the new handler if the signal disposition isn't SIG_IGN, + // save the old one in RegisteredSignalInfo. + struct sigaction act; + sigaction(Signal, NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA); RegisteredSignalInfo[Index].SigNo = Signal; ++NumRegisteredSignals; }; @@ -411,14 +415,12 @@ static void SignalHandler(int Sig, siginfo_t *Info, void *) { // Otherwise if it is a fault (like SEGV) run any handler. llvm::sys::RunSignalHandlers(); -#ifdef __s390__ - // On S/390, certain signals are delivered with PSW Address pointing to - // *after* the faulting instruction. Simply returning from the signal - // handler would continue execution after that point, instead of - // re-raising the signal. Raise the signal manually in those cases. - if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP) - raise(Sig); -#endif + // Resignal if it is a kill signal so that the exit code contains the + // terminating signal number. + if (llvm::is_contained(KillSigs, Sig)) { + raise(Sig); // Execute the default handler. + return; + } #if defined(__linux__) // Re-raising a signal via `raise` loses the original siginfo. Recent @@ -441,6 +443,11 @@ static void InfoSignalHandler(int Sig) { SaveAndRestore SaveErrnoDuringASignalHandler(errno); if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction) CurrentInfoFunction(); + + if (Sig == SIGUSR1) { + sys::unregisterHandlers(); + raise(Sig); + } } void sys::RunInterruptHandlers() { >From ff86338f168dcf39ae6a50ddea3fdfdeba47d2a9 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Fri, 9 Jan 2026 12:41:58 -0500 Subject: [PATCH 02/10] Address comments to only change the Clang's behavior according to the POSIX specification for utilities. Update test cases to reflect they failed because of signal/crash. --- .../unittests/ThreadCrashReporterTests.cpp | 12 ------------ clang/test/Driver/crash-diagnostics-dir-3.c | 2 +- clang/test/Driver/crash-diagnostics-dir.c | 2 +- clang/test/Driver/crash-ir-repro.cpp | 2 +- clang/test/Driver/crash-report-clang-cl.cpp | 2 +- clang/test/Driver/crash-report-header.h | 2 +- clang/test/Driver/crash-report-spaces.c | 2 +- clang/test/Driver/crash-report-with-asserts.c | 4 ++-- clang/test/Driver/crash-report.cpp | 4 ++-- clang/test/Driver/emit-reproducer.c | 14 +++++++------- clang/test/Driver/output-file-cleanup.c | 2 +- llvm/cmake/modules/AddLLVM.cmake | 7 +++++++ .../cmake/modules/llvm-driver-template.cpp.in | 2 +- llvm/include/llvm/Support/InitLLVM.h | 8 +++++--- llvm/include/llvm/Support/Signals.h | 2 +- llvm/lib/Support/InitLLVM.cpp | 5 +++-- llvm/lib/Support/Unix/Signals.inc | 19 +++++++++++++++---- 17 files changed, 50 insertions(+), 41 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp b/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp index 1c86fcbea4a4b..0eb8d472c6702 100644 --- a/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp +++ b/clang-tools-extra/clangd/unittests/ThreadCrashReporterTests.cpp @@ -13,17 +13,6 @@ #include <csignal> #include <string> -// According to the POSIX specification, if the inherited disposition of a -// signal is the default action, the behavior of utilitys must be as if the -// default action had been taken. When the required default action is to -// terminate the process, such as for SIGUSR1, the utility may catch the -// signal, perform additional processing, restore the default disposition, -// and then re-signal itself. This causes the process to terminate as -// required. Because of this behavior, the crash-reporter test here is not -// suitable for Unix platforms. - -#ifndef LLVM_ON_UNIX - namespace clang { namespace clangd { @@ -87,4 +76,3 @@ TEST(ThreadCrashReporterTest, All) { } // namespace } // namespace clangd } // namespace clang -#endif // !LLVM_ON_UNIX diff --git a/clang/test/Driver/crash-diagnostics-dir-3.c b/clang/test/Driver/crash-diagnostics-dir-3.c index a91bc48d7e462..8d22df85abd2f 100644 --- a/clang/test/Driver/crash-diagnostics-dir-3.c +++ b/clang/test/Driver/crash-diagnostics-dir-3.c @@ -1,6 +1,6 @@ // RUN: export LSAN_OPTIONS=detect_leaks=0 // RUN: rm -rf %t -// RUN: not env CLANG_CRASH_DIAGNOSTICS_DIR=%t %clang -c %s -o - 2>&1 | FileCheck %s +// RUN: not --crash 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/clang/test/Driver/crash-diagnostics-dir.c b/clang/test/Driver/crash-diagnostics-dir.c index 16382eff1cde7..56c77beae7234 100644 --- a/clang/test/Driver/crash-diagnostics-dir.c +++ b/clang/test/Driver/crash-diagnostics-dir.c @@ -1,6 +1,6 @@ // RUN: export LSAN_OPTIONS=detect_leaks=0 // RUN: rm -rf %t -// RUN: not %clang -fcrash-diagnostics-dir=%t -c %s -o - 2>&1 | FileCheck %s +// RUN: not --crash %clang -fcrash-diagnostics-dir=%t -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.c.tmp{{(/|\\).*}}.c diff --git a/clang/test/Driver/crash-ir-repro.cpp b/clang/test/Driver/crash-ir-repro.cpp index 217d5ed421bdb..9d40238e76a23 100644 --- a/clang/test/Driver/crash-ir-repro.cpp +++ b/clang/test/Driver/crash-ir-repro.cpp @@ -1,5 +1,5 @@ // RUN: %clang -S -emit-llvm -o %t.ll %s -// RUN: not %clang -S -DCRASH %s -o %t.ll 2>&1 | FileCheck %s +// RUN: not --crash %clang -S -DCRASH %s -o %t.ll 2>&1 | FileCheck %s // TODO(boomanaiden154): This test case causes clang to raise a signal when // running under ubsan, but not in normal build configurations. This should diff --git a/clang/test/Driver/crash-report-clang-cl.cpp b/clang/test/Driver/crash-report-clang-cl.cpp index 963c3b6d0ab03..3efeb8088db52 100644 --- a/clang/test/Driver/crash-report-clang-cl.cpp +++ b/clang/test/Driver/crash-report-clang-cl.cpp @@ -2,7 +2,7 @@ // RUN: rm -rf %t // RUN: mkdir %t -// RUN: not %clang_cl -fsyntax-only /Brepro /source-charset:utf-8 \ +// RUN: not --crash %clang_cl -fsyntax-only /Brepro /source-charset:utf-8 \ // RUN: -fcrash-diagnostics-dir=%t -- %s 2>&1 | FileCheck %s // RUN: cat %t/crash-report-clang-cl-*.cpp | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-clang-cl-*.sh | FileCheck --check-prefix=CHECKSH %s diff --git a/clang/test/Driver/crash-report-header.h b/clang/test/Driver/crash-report-header.h index 04865a0cc300f..31c71ff625c05 100644 --- a/clang/test/Driver/crash-report-header.h +++ b/clang/test/Driver/crash-report-header.h @@ -1,7 +1,7 @@ // RUN: export LSAN_OPTIONS=detect_leaks=0 // RUN: rm -rf %t // RUN: mkdir %t -// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not %clang -fsyntax-only %s 2>&1 | FileCheck %s +// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not --crash %clang -fsyntax-only %s 2>&1 | FileCheck %s // RUN: cat %t/crash-report-header-*.h | FileCheck --check-prefix=CHECKSRC "%s" // RUN: cat %t/crash-report-header-*.sh | FileCheck --check-prefix=CHECKSH "%s" // REQUIRES: crash-recovery diff --git a/clang/test/Driver/crash-report-spaces.c b/clang/test/Driver/crash-report-spaces.c index b4d8ac1f57e83..c01c8df0552de 100644 --- a/clang/test/Driver/crash-report-spaces.c +++ b/clang/test/Driver/crash-report-spaces.c @@ -2,7 +2,7 @@ // RUN: rm -rf "%t" // RUN: mkdir "%t" // RUN: cp "%s" "%t/crash report spaces.c" -// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not %clang -fsyntax-only "%t/crash report spaces.c" 2>&1 | FileCheck "%s" +// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not --crash %clang -fsyntax-only "%t/crash report spaces.c" 2>&1 | FileCheck "%s" // RUN: cat "%t/crash report spaces"-*.c | FileCheck --check-prefix=CHECKSRC "%s" // RUN: cat "%t/crash report spaces"-*.sh | FileCheck --check-prefix=CHECKSH "%s" // REQUIRES: crash-recovery diff --git a/clang/test/Driver/crash-report-with-asserts.c b/clang/test/Driver/crash-report-with-asserts.c index 686c49f339fb7..0b619d9ec2f46 100644 --- a/clang/test/Driver/crash-report-with-asserts.c +++ b/clang/test/Driver/crash-report-with-asserts.c @@ -12,13 +12,13 @@ // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not %clang %s @%t.rsp -DASSERT 2>&1 | FileCheck %s +// RUN: not --crash %clang %s @%t.rsp -DASSERT 2>&1 | FileCheck %s // RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not %clang %s @%t.rsp -DUNREACHABLE 2>&1 | FileCheck %s +// RUN: not --crash %clang %s @%t.rsp -DUNREACHABLE 2>&1 | FileCheck %s // RUN: cat %t/crash-report-with-asserts-*.c | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-with-asserts-*.sh | FileCheck --check-prefix=CHECKSH %s diff --git a/clang/test/Driver/crash-report.cpp b/clang/test/Driver/crash-report.cpp index 59eee65af57ee..4b5adfc02bff4 100644 --- a/clang/test/Driver/crash-report.cpp +++ b/clang/test/Driver/crash-report.cpp @@ -12,13 +12,13 @@ // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not %clang %s @%t.rsp -DPARSER 2>&1 | FileCheck %s +// RUN: not --crash %clang %s @%t.rsp -DPARSER 2>&1 | FileCheck %s // RUN: cat %t/crash-report-*.cpp | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not %clang %s @%t.rsp -DCRASH 2>&1 | FileCheck %s +// RUN: not --crash %clang %s @%t.rsp -DCRASH 2>&1 | FileCheck %s // RUN: cat %t/crash-report-*.cpp | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s diff --git a/clang/test/Driver/emit-reproducer.c b/clang/test/Driver/emit-reproducer.c index 18e1b4e41b91d..28c585193a7d0 100644 --- a/clang/test/Driver/emit-reproducer.c +++ b/clang/test/Driver/emit-reproducer.c @@ -3,13 +3,13 @@ // RUN: echo "%s -fcrash-diagnostics-dir=%t -fsyntax-only" | sed -e 's/\\/\\\\/g' > %t.rsp -// RUN: not %clang -DFATAL @%t.rsp -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DFATAL @%t.rsp -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DFATAL @%t.rsp 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL @%t.rsp -gen-reproducer=crash 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL @%t.rsp -gen-reproducer=error 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL @%t.rsp -gen-reproducer=always 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL @%t.rsp -gen-reproducer 2>&1 | FileCheck %s +// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT +// RUN: not --crash %clang -DFATAL @%t.rsp -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT +// RUN: not --crash %clang -DFATAL @%t.rsp 2>&1 | FileCheck %s +// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=crash 2>&1 | FileCheck %s +// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=error 2>&1 | FileCheck %s +// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=always 2>&1 | FileCheck %s +// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer 2>&1 | FileCheck %s // RUN: not %clang -DERROR @%t.rsp -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT // RUN: not %clang -DERROR @%t.rsp -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT diff --git a/clang/test/Driver/output-file-cleanup.c b/clang/test/Driver/output-file-cleanup.c index 3628df8192652..b5f548dc0b01a 100644 --- a/clang/test/Driver/output-file-cleanup.c +++ b/clang/test/Driver/output-file-cleanup.c @@ -2,7 +2,7 @@ // RUN: rm -f "%t.d" "%t1.s" "%t2.s" "%t3.s" "%t4.s" "%t5.s" // // RUN: touch %t.s -// RUN: not %clang -S -DCRASH -o %t.s -MMD -MF %t.d %s +// RUN: not --crash %clang -S -DCRASH -o %t.s -MMD -MF %t.d %s // RUN: test ! -f %t.s // RUN: test ! -f %t.d diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index d938214f9d0df..b4ca46a874067 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1004,6 +1004,13 @@ macro(generate_llvm_objects name) if (ARG_GENERATE_DRIVER) string(REPLACE "-" "_" TOOL_NAME ${name}) + + set(INITLLVM_ARGS "") + + if(${name} STREQUAL "clang") + set(INITLLVM_ARGS ", /*InstallPipeSignalExitHandler=*/true, /*IsClangDriver=*/true") + endif() + foreach(path ${CMAKE_MODULE_PATH}) if(EXISTS ${path}/llvm-driver-template.cpp.in) configure_file( diff --git a/llvm/cmake/modules/llvm-driver-template.cpp.in b/llvm/cmake/modules/llvm-driver-template.cpp.in index 1470ef1f06164..d4c385c8cf412 100644 --- a/llvm/cmake/modules/llvm-driver-template.cpp.in +++ b/llvm/cmake/modules/llvm-driver-template.cpp.in @@ -13,6 +13,6 @@ int @TOOL_NAME@_main(int argc, char **, const llvm::ToolContext &); int main(int argc, char **argv) { - llvm::InitLLVM X(argc, argv); + llvm::InitLLVM X(argc, argv@INITLLVM_ARGS@); return @TOOL_NAME@_main(argc, argv, {argv[0], nullptr, false}); } diff --git a/llvm/include/llvm/Support/InitLLVM.h b/llvm/include/llvm/Support/InitLLVM.h index 748f5d8aa6aea..1473026e2974a 100644 --- a/llvm/include/llvm/Support/InitLLVM.h +++ b/llvm/include/llvm/Support/InitLLVM.h @@ -36,10 +36,12 @@ namespace llvm { class InitLLVM { public: LLVM_ABI InitLLVM(int &Argc, const char **&Argv, - bool InstallPipeSignalExitHandler = true); - InitLLVM(int &Argc, char **&Argv, bool InstallPipeSignalExitHandler = true) + bool InstallPipeSignalExitHandler = true, + bool IsClandDriver = false); + InitLLVM(int &Argc, char **&Argv, bool InstallPipeSignalExitHandler = true, + bool IsClangDriver = false) : InitLLVM(Argc, const_cast<const char **&>(Argv), - InstallPipeSignalExitHandler) {} + InstallPipeSignalExitHandler, IsClangDriver) {} LLVM_ABI ~InitLLVM(); diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h index 21b425fffef53..22612a55b3a37 100644 --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -100,7 +100,7 @@ using SignalHandlerCallback = void (*)(void *); /// Add a function to be called when an abort/kill signal is delivered to the /// process. The handler can have a cookie passed to it to identify what /// instance of the handler it is. -LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie); +LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, bool IsClangDriver = false); /// This function registers a function to be called when the user "interrupts" /// the program (typically by pressing ctrl-c). When the user interrupts the diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index b90f4e0714458..248250cc5ddcb 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -73,7 +73,8 @@ using namespace llvm; using namespace llvm::sys; InitLLVM::InitLLVM(int &Argc, const char **&Argv, - bool InstallPipeSignalExitHandler) { + bool InstallPipeSignalExitHandler, + bool IsClangDriver) { #ifndef NDEBUG static std::atomic<bool> Initialized{false}; assert(!Initialized && "InitLLVM was already initialized!"); @@ -81,7 +82,7 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, #endif // Bring stdin/stdout/stderr into a known state. - sys::AddSignalHandler(CleanupStdHandles, nullptr); + sys::AddSignalHandler(CleanupStdHandles, nullptr, IsClangDriver); if (InstallPipeSignalExitHandler) // The pipe signal handler must be installed before any other handlers are diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index 35ac441d73be8..1d1cc9c915a72 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -86,6 +86,7 @@ using namespace llvm; static void SignalHandler(int Sig, siginfo_t *Info, void *); static void InfoSignalHandler(int Sig); // defined below. +static void InfoSignalHandlerTerminate(int Sig); // defined below. using SignalHandlerFunctionType = void (*)(); /// The function to call if ctrl-c is pressed. @@ -292,7 +293,7 @@ static void CreateSigAltStack() { static void CreateSigAltStack() {} #endif -static void RegisterHandlers() { // Not signal-safe. +static void RegisterHandlers(bool IsClangDriver = false) { // Not signal-safe. // The mutex prevents other threads from registering handlers while we're // doing it. We also have to protect the handlers and their count because // a signal handler could fire while we're registering handlers. @@ -321,7 +322,12 @@ static void RegisterHandlers() { // Not signal-safe. NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK | SA_SIGINFO; break; case SignalKind::IsInfo: - NewHandler.sa_handler = InfoSignalHandler; + if (IsClangDriver) + // If it is the Clang driver the signal handler resignal itself to + // terminate after handling the signal. + NewHandler.sa_handler = InfoSignalHandlerTerminate; + else + NewHandler.sa_handler = InfoSignalHandler; NewHandler.sa_flags = SA_ONSTACK; break; } @@ -443,6 +449,10 @@ static void InfoSignalHandler(int Sig) { SaveAndRestore SaveErrnoDuringASignalHandler(errno); if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction) CurrentInfoFunction(); +} + +static void InfoSignalHandlerTerminate(int Sig) { + InfoSignalHandler(Sig); if (Sig == SIGUSR1) { sys::unregisterHandlers(); @@ -496,9 +506,10 @@ void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { /// handler can have a cookie passed to it to identify what instance of the /// handler it is. void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, - void *Cookie) { // Signal-safe. + void *Cookie, bool IsClangDriver) { + // Signal-safe. insertSignalHandler(FnPtr, Cookie); - RegisterHandlers(); + RegisterHandlers(IsClangDriver); } #if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \ >From ec229ade8743b31d3c546d54cdf874a49134114d Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Fri, 9 Jan 2026 12:52:48 -0500 Subject: [PATCH 03/10] Fix formatting. --- llvm/include/llvm/Support/InitLLVM.h | 2 +- llvm/include/llvm/Support/Signals.h | 3 ++- llvm/lib/Support/InitLLVM.cpp | 3 +-- llvm/lib/Support/Unix/Signals.inc | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/Support/InitLLVM.h b/llvm/include/llvm/Support/InitLLVM.h index 1473026e2974a..6859964bd8f22 100644 --- a/llvm/include/llvm/Support/InitLLVM.h +++ b/llvm/include/llvm/Support/InitLLVM.h @@ -39,7 +39,7 @@ class InitLLVM { bool InstallPipeSignalExitHandler = true, bool IsClandDriver = false); InitLLVM(int &Argc, char **&Argv, bool InstallPipeSignalExitHandler = true, - bool IsClangDriver = false) + bool IsClangDriver = false) : InitLLVM(Argc, const_cast<const char **&>(Argv), InstallPipeSignalExitHandler, IsClangDriver) {} diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h index 22612a55b3a37..9d8fa97eb50b5 100644 --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -100,7 +100,8 @@ using SignalHandlerCallback = void (*)(void *); /// Add a function to be called when an abort/kill signal is delivered to the /// process. The handler can have a cookie passed to it to identify what /// instance of the handler it is. -LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, bool IsClangDriver = false); +LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, + bool IsClangDriver = false); /// This function registers a function to be called when the user "interrupts" /// the program (typically by pressing ctrl-c). When the user interrupts the diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index 248250cc5ddcb..795e9ab0bcf88 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -73,8 +73,7 @@ using namespace llvm; using namespace llvm::sys; InitLLVM::InitLLVM(int &Argc, const char **&Argv, - bool InstallPipeSignalExitHandler, - bool IsClangDriver) { + bool InstallPipeSignalExitHandler, bool IsClangDriver) { #ifndef NDEBUG static std::atomic<bool> Initialized{false}; assert(!Initialized && "InitLLVM was already initialized!"); diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index 1d1cc9c915a72..ad387bc0f0965 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -505,9 +505,9 @@ void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { /// Add a function to be called when a signal is delivered to the process. The /// handler can have a cookie passed to it to identify what instance of the /// handler it is. -void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, - void *Cookie, bool IsClangDriver) { - // Signal-safe. +void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie, + bool IsClangDriver) { + // Signal-safe. insertSignalHandler(FnPtr, Cookie); RegisterHandlers(IsClangDriver); } >From cc01f5a69ba5c4ed3aca7da30fae4fcb5f336460 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Fri, 9 Jan 2026 15:23:09 -0500 Subject: [PATCH 04/10] Use a different AddSignalHandler signature for Windows. --- llvm/include/llvm/Support/Signals.h | 8 +++++++- llvm/lib/Support/InitLLVM.cpp | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h index 9d8fa97eb50b5..7745927dc5258 100644 --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -99,9 +99,15 @@ using SignalHandlerCallback = void (*)(void *); /// Add a function to be called when an abort/kill signal is delivered to the /// process. The handler can have a cookie passed to it to identify what -/// instance of the handler it is. +/// instance of the handler it is. On Unix systems, the argument IsClangDriver +/// indicates whether the function is called from a Clang driver so that the +/// implementation ensures the Clang signal handling complies with POSIX. +#ifdef _WIN32 +LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie); +#else LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, bool IsClangDriver = false); +#endif /// This function registers a function to be called when the user "interrupts" /// the program (typically by pressing ctrl-c). When the user interrupts the diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index 795e9ab0bcf88..2feb0b495d3eb 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -81,7 +81,11 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, #endif // Bring stdin/stdout/stderr into a known state. +#ifdef _WIN32 + sys::AddSignalHandler(CleanupStdHandles, nullptr); +#else sys::AddSignalHandler(CleanupStdHandles, nullptr, IsClangDriver); +#endif if (InstallPipeSignalExitHandler) // The pipe signal handler must be installed before any other handlers are >From c3f220e8842da3ae4af39ab1421667cfa10bfca0 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Fri, 9 Jan 2026 17:19:01 -0500 Subject: [PATCH 05/10] Define and use macro '%crash_opt'. It is '--crash' if it is not Windows. Otherwise, it is nothing. --- clang/test/Driver/crash-diagnostics-dir-3.c | 2 +- clang/test/Driver/crash-diagnostics-dir.c | 2 +- clang/test/Driver/crash-ir-repro.cpp | 2 +- clang/test/Driver/crash-report-clang-cl.cpp | 2 +- clang/test/Driver/crash-report-header.h | 2 +- clang/test/Driver/crash-report-spaces.c | 2 +- clang/test/Driver/crash-report-with-asserts.c | 4 ++-- clang/test/Driver/crash-report.cpp | 4 ++-- clang/test/Driver/emit-reproducer.c | 14 +++++++------- clang/test/Driver/lit.local.cfg | 7 +++++++ clang/test/Driver/output-file-cleanup.c | 2 +- 11 files changed, 25 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/crash-diagnostics-dir-3.c b/clang/test/Driver/crash-diagnostics-dir-3.c index 8d22df85abd2f..63a5efc853a4c 100644 --- a/clang/test/Driver/crash-diagnostics-dir-3.c +++ b/clang/test/Driver/crash-diagnostics-dir-3.c @@ -1,6 +1,6 @@ // RUN: export LSAN_OPTIONS=detect_leaks=0 // RUN: rm -rf %t -// RUN: not --crash env CLANG_CRASH_DIAGNOSTICS_DIR=%t %clang -c %s -o - 2>&1 | FileCheck %s +// RUN: not %crash_opt 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/clang/test/Driver/crash-diagnostics-dir.c b/clang/test/Driver/crash-diagnostics-dir.c index 56c77beae7234..9a8299bffe005 100644 --- a/clang/test/Driver/crash-diagnostics-dir.c +++ b/clang/test/Driver/crash-diagnostics-dir.c @@ -1,6 +1,6 @@ // RUN: export LSAN_OPTIONS=detect_leaks=0 // RUN: rm -rf %t -// RUN: not --crash %clang -fcrash-diagnostics-dir=%t -c %s -o - 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -fcrash-diagnostics-dir=%t -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.c.tmp{{(/|\\).*}}.c diff --git a/clang/test/Driver/crash-ir-repro.cpp b/clang/test/Driver/crash-ir-repro.cpp index 9d40238e76a23..1a2000ad1279f 100644 --- a/clang/test/Driver/crash-ir-repro.cpp +++ b/clang/test/Driver/crash-ir-repro.cpp @@ -1,5 +1,5 @@ // RUN: %clang -S -emit-llvm -o %t.ll %s -// RUN: not --crash %clang -S -DCRASH %s -o %t.ll 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -S -DCRASH %s -o %t.ll 2>&1 | FileCheck %s // TODO(boomanaiden154): This test case causes clang to raise a signal when // running under ubsan, but not in normal build configurations. This should diff --git a/clang/test/Driver/crash-report-clang-cl.cpp b/clang/test/Driver/crash-report-clang-cl.cpp index 3efeb8088db52..f61b94626f584 100644 --- a/clang/test/Driver/crash-report-clang-cl.cpp +++ b/clang/test/Driver/crash-report-clang-cl.cpp @@ -2,7 +2,7 @@ // RUN: rm -rf %t // RUN: mkdir %t -// RUN: not --crash %clang_cl -fsyntax-only /Brepro /source-charset:utf-8 \ +// RUN: not %crash_opt %clang_cl -fsyntax-only /Brepro /source-charset:utf-8 \ // RUN: -fcrash-diagnostics-dir=%t -- %s 2>&1 | FileCheck %s // RUN: cat %t/crash-report-clang-cl-*.cpp | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-clang-cl-*.sh | FileCheck --check-prefix=CHECKSH %s diff --git a/clang/test/Driver/crash-report-header.h b/clang/test/Driver/crash-report-header.h index 31c71ff625c05..6d5156537126d 100644 --- a/clang/test/Driver/crash-report-header.h +++ b/clang/test/Driver/crash-report-header.h @@ -1,7 +1,7 @@ // RUN: export LSAN_OPTIONS=detect_leaks=0 // RUN: rm -rf %t // RUN: mkdir %t -// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not --crash %clang -fsyntax-only %s 2>&1 | FileCheck %s +// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not %crash_opt %clang -fsyntax-only %s 2>&1 | FileCheck %s // RUN: cat %t/crash-report-header-*.h | FileCheck --check-prefix=CHECKSRC "%s" // RUN: cat %t/crash-report-header-*.sh | FileCheck --check-prefix=CHECKSH "%s" // REQUIRES: crash-recovery diff --git a/clang/test/Driver/crash-report-spaces.c b/clang/test/Driver/crash-report-spaces.c index c01c8df0552de..b5fbb59683fc0 100644 --- a/clang/test/Driver/crash-report-spaces.c +++ b/clang/test/Driver/crash-report-spaces.c @@ -2,7 +2,7 @@ // RUN: rm -rf "%t" // RUN: mkdir "%t" // RUN: cp "%s" "%t/crash report spaces.c" -// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not --crash %clang -fsyntax-only "%t/crash report spaces.c" 2>&1 | FileCheck "%s" +// RUN: env TMPDIR="%t" TEMP="%t" TMP="%t" RC_DEBUG_OPTIONS=1 not %crash_opt %clang -fsyntax-only "%t/crash report spaces.c" 2>&1 | FileCheck "%s" // RUN: cat "%t/crash report spaces"-*.c | FileCheck --check-prefix=CHECKSRC "%s" // RUN: cat "%t/crash report spaces"-*.sh | FileCheck --check-prefix=CHECKSH "%s" // REQUIRES: crash-recovery diff --git a/clang/test/Driver/crash-report-with-asserts.c b/clang/test/Driver/crash-report-with-asserts.c index 0b619d9ec2f46..278860a9158e4 100644 --- a/clang/test/Driver/crash-report-with-asserts.c +++ b/clang/test/Driver/crash-report-with-asserts.c @@ -12,13 +12,13 @@ // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not --crash %clang %s @%t.rsp -DASSERT 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang %s @%t.rsp -DASSERT 2>&1 | FileCheck %s // RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not --crash %clang %s @%t.rsp -DUNREACHABLE 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang %s @%t.rsp -DUNREACHABLE 2>&1 | FileCheck %s // RUN: cat %t/crash-report-with-asserts-*.c | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-with-asserts-*.sh | FileCheck --check-prefix=CHECKSH %s diff --git a/clang/test/Driver/crash-report.cpp b/clang/test/Driver/crash-report.cpp index 4b5adfc02bff4..c431940bf9ea1 100644 --- a/clang/test/Driver/crash-report.cpp +++ b/clang/test/Driver/crash-report.cpp @@ -12,13 +12,13 @@ // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not --crash %clang %s @%t.rsp -DPARSER 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang %s @%t.rsp -DPARSER 2>&1 | FileCheck %s // RUN: cat %t/crash-report-*.cpp | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s // RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \ // RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \ -// RUN: not --crash %clang %s @%t.rsp -DCRASH 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang %s @%t.rsp -DCRASH 2>&1 | FileCheck %s // RUN: cat %t/crash-report-*.cpp | FileCheck --check-prefix=CHECKSRC %s // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s diff --git a/clang/test/Driver/emit-reproducer.c b/clang/test/Driver/emit-reproducer.c index 28c585193a7d0..6fd1735ee8549 100644 --- a/clang/test/Driver/emit-reproducer.c +++ b/clang/test/Driver/emit-reproducer.c @@ -3,13 +3,13 @@ // RUN: echo "%s -fcrash-diagnostics-dir=%t -fsyntax-only" | sed -e 's/\\/\\\\/g' > %t.rsp -// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not --crash %clang -DFATAL @%t.rsp -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not --crash %clang -DFATAL @%t.rsp 2>&1 | FileCheck %s -// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=crash 2>&1 | FileCheck %s -// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=error 2>&1 | FileCheck %s -// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer=always 2>&1 | FileCheck %s -// RUN: not --crash %clang -DFATAL @%t.rsp -gen-reproducer 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -DFATAL @%t.rsp -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT +// RUN: not %crash_opt %clang -DFATAL @%t.rsp -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT +// RUN: not %crash_opt %clang -DFATAL @%t.rsp 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -DFATAL @%t.rsp -gen-reproducer=crash 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -DFATAL @%t.rsp -gen-reproducer=error 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -DFATAL @%t.rsp -gen-reproducer=always 2>&1 | FileCheck %s +// RUN: not %crash_opt %clang -DFATAL @%t.rsp -gen-reproducer 2>&1 | FileCheck %s // RUN: not %clang -DERROR @%t.rsp -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT // RUN: not %clang -DERROR @%t.rsp -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg index 6370e9f92d89b..a47d0de90d763 100644 --- a/clang/test/Driver/lit.local.cfg +++ b/clang/test/Driver/lit.local.cfg @@ -1,4 +1,5 @@ from lit.llvm import llvm_config +import sys config.suffixes = [ ".c", @@ -27,6 +28,12 @@ config.substitutions.insert( 0, ("%clang_cc1", """*** Do not use 'clang -cc1' in Driver tests. ***""") ) +is_windows = sys.platform.startswith("win") +if is_windows: + config.substitutions.append(('%crash_opt', '')) +else: + config.substitutions.append(('%crash_opt', '--crash')) + # Remove harmful environmental variables for clang Driver tests. # Some might be useful for other tests so they are only removed here. driver_overwrite_env_vars = [ diff --git a/clang/test/Driver/output-file-cleanup.c b/clang/test/Driver/output-file-cleanup.c index b5f548dc0b01a..432ff640656e7 100644 --- a/clang/test/Driver/output-file-cleanup.c +++ b/clang/test/Driver/output-file-cleanup.c @@ -2,7 +2,7 @@ // RUN: rm -f "%t.d" "%t1.s" "%t2.s" "%t3.s" "%t4.s" "%t5.s" // // RUN: touch %t.s -// RUN: not --crash %clang -S -DCRASH -o %t.s -MMD -MF %t.d %s +// RUN: not %crash_opt %clang -S -DCRASH -o %t.s -MMD -MF %t.d %s // RUN: test ! -f %t.s // RUN: test ! -f %t.d >From 8b132975ae34413760d8a49b42ee256c629ef537 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Mon, 2 Feb 2026 12:50:24 -0500 Subject: [PATCH 06/10] Addressed comment: - rename IsClangDriver to NeedsPOSIXUtilitySignalHandling --- llvm/cmake/modules/AddLLVM.cmake | 2 +- llvm/include/llvm/Support/InitLLVM.h | 4 ++-- llvm/include/llvm/Support/Signals.h | 9 +++++---- llvm/lib/Support/InitLLVM.cpp | 4 ++-- llvm/lib/Support/Unix/Signals.inc | 12 ++++++------ 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index b4ca46a874067..81aaf6034cca7 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1008,7 +1008,7 @@ macro(generate_llvm_objects name) set(INITLLVM_ARGS "") if(${name} STREQUAL "clang") - set(INITLLVM_ARGS ", /*InstallPipeSignalExitHandler=*/true, /*IsClangDriver=*/true") + set(INITLLVM_ARGS ", /*InstallPipeSignalExitHandler=*/true, /*NeedsPOSIXUtilitySignalHandling=*/true") endif() foreach(path ${CMAKE_MODULE_PATH}) diff --git a/llvm/include/llvm/Support/InitLLVM.h b/llvm/include/llvm/Support/InitLLVM.h index 6859964bd8f22..616e1baf6ad76 100644 --- a/llvm/include/llvm/Support/InitLLVM.h +++ b/llvm/include/llvm/Support/InitLLVM.h @@ -39,9 +39,9 @@ class InitLLVM { bool InstallPipeSignalExitHandler = true, bool IsClandDriver = false); InitLLVM(int &Argc, char **&Argv, bool InstallPipeSignalExitHandler = true, - bool IsClangDriver = false) + bool NeedsPOSIXUtilitySignalHandling = false) : InitLLVM(Argc, const_cast<const char **&>(Argv), - InstallPipeSignalExitHandler, IsClangDriver) {} + InstallPipeSignalExitHandler, NeedsPOSIXUtilitySignalHandling) {} LLVM_ABI ~InitLLVM(); diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h index 7745927dc5258..916d0ed7dea69 100644 --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -99,14 +99,15 @@ using SignalHandlerCallback = void (*)(void *); /// Add a function to be called when an abort/kill signal is delivered to the /// process. The handler can have a cookie passed to it to identify what -/// instance of the handler it is. On Unix systems, the argument IsClangDriver -/// indicates whether the function is called from a Clang driver so that the -/// implementation ensures the Clang signal handling complies with POSIX. +/// instance of the handler it is. On Unix systems, the +/// NeedsPOSIXUtilitySignalHandling argument indicates whether POSIX signal +/// handling semantics are followed, so that the signal handler resignals +/// itself to terminate after handling the signal. #ifdef _WIN32 LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie); #else LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, - bool IsClangDriver = false); + bool NeedsPOSIXUtilitySignalHandling = false); #endif /// This function registers a function to be called when the user "interrupts" diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index 2feb0b495d3eb..d214daf437e27 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -73,7 +73,7 @@ using namespace llvm; using namespace llvm::sys; InitLLVM::InitLLVM(int &Argc, const char **&Argv, - bool InstallPipeSignalExitHandler, bool IsClangDriver) { + bool InstallPipeSignalExitHandler, bool NeedsPOSIXUtilitySignalHandling) { #ifndef NDEBUG static std::atomic<bool> Initialized{false}; assert(!Initialized && "InitLLVM was already initialized!"); @@ -84,7 +84,7 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, #ifdef _WIN32 sys::AddSignalHandler(CleanupStdHandles, nullptr); #else - sys::AddSignalHandler(CleanupStdHandles, nullptr, IsClangDriver); + sys::AddSignalHandler(CleanupStdHandles, nullptr, NeedsPOSIXUtilitySignalHandling); #endif if (InstallPipeSignalExitHandler) diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index ad387bc0f0965..dffbe2146aaa5 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -293,7 +293,7 @@ static void CreateSigAltStack() { static void CreateSigAltStack() {} #endif -static void RegisterHandlers(bool IsClangDriver = false) { // Not signal-safe. +static void RegisterHandlers(bool NeedsPOSIXUtilitySignalHandling = false) { // Not signal-safe. // The mutex prevents other threads from registering handlers while we're // doing it. We also have to protect the handlers and their count because // a signal handler could fire while we're registering handlers. @@ -322,9 +322,9 @@ static void RegisterHandlers(bool IsClangDriver = false) { // Not signal-safe. NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK | SA_SIGINFO; break; case SignalKind::IsInfo: - if (IsClangDriver) - // If it is the Clang driver the signal handler resignal itself to - // terminate after handling the signal. + if (NeedsPOSIXUtilitySignalHandling) + // If POSIX signal-handling semantics are followed, the signal handler + // resignal itself to terminate after handling the signal. NewHandler.sa_handler = InfoSignalHandlerTerminate; else NewHandler.sa_handler = InfoSignalHandler; @@ -506,10 +506,10 @@ void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { /// handler can have a cookie passed to it to identify what instance of the /// handler it is. void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie, - bool IsClangDriver) { + bool NeedsPOSIXUtilitySignalHandling) { // Signal-safe. insertSignalHandler(FnPtr, Cookie); - RegisterHandlers(IsClangDriver); + RegisterHandlers(NeedsPOSIXUtilitySignalHandling); } #if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \ >From 4ecbc5ba964bde2247b619935bfd44eaa9a8f87f Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Mon, 2 Feb 2026 13:01:58 -0500 Subject: [PATCH 07/10] Fix formatting. --- llvm/include/llvm/Support/InitLLVM.h | 3 ++- llvm/lib/Support/InitLLVM.cpp | 6 ++++-- llvm/lib/Support/Unix/Signals.inc | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Support/InitLLVM.h b/llvm/include/llvm/Support/InitLLVM.h index 616e1baf6ad76..02a315790e139 100644 --- a/llvm/include/llvm/Support/InitLLVM.h +++ b/llvm/include/llvm/Support/InitLLVM.h @@ -41,7 +41,8 @@ class InitLLVM { InitLLVM(int &Argc, char **&Argv, bool InstallPipeSignalExitHandler = true, bool NeedsPOSIXUtilitySignalHandling = false) : InitLLVM(Argc, const_cast<const char **&>(Argv), - InstallPipeSignalExitHandler, NeedsPOSIXUtilitySignalHandling) {} + InstallPipeSignalExitHandler, + NeedsPOSIXUtilitySignalHandling) {} LLVM_ABI ~InitLLVM(); diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index d214daf437e27..797c5d35bec35 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -73,7 +73,8 @@ using namespace llvm; using namespace llvm::sys; InitLLVM::InitLLVM(int &Argc, const char **&Argv, - bool InstallPipeSignalExitHandler, bool NeedsPOSIXUtilitySignalHandling) { + bool InstallPipeSignalExitHandler, + bool NeedsPOSIXUtilitySignalHandling) { #ifndef NDEBUG static std::atomic<bool> Initialized{false}; assert(!Initialized && "InitLLVM was already initialized!"); @@ -84,7 +85,8 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, #ifdef _WIN32 sys::AddSignalHandler(CleanupStdHandles, nullptr); #else - sys::AddSignalHandler(CleanupStdHandles, nullptr, NeedsPOSIXUtilitySignalHandling); + sys::AddSignalHandler(CleanupStdHandles, nullptr, + NeedsPOSIXUtilitySignalHandling); #endif if (InstallPipeSignalExitHandler) diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index dffbe2146aaa5..d7f1368428694 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -293,7 +293,8 @@ static void CreateSigAltStack() { static void CreateSigAltStack() {} #endif -static void RegisterHandlers(bool NeedsPOSIXUtilitySignalHandling = false) { // Not signal-safe. +static void RegisterHandlers( + bool NeedsPOSIXUtilitySignalHandling = false) { // Not signal-safe. // The mutex prevents other threads from registering handlers while we're // doing it. We also have to protect the handlers and their count because // a signal handler could fire while we're registering handlers. >From 1ccd5fe4ea28621d847c4236d1d3143d45539b76 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Mon, 9 Feb 2026 11:07:54 -0500 Subject: [PATCH 08/10] Address comments: * correct the argument name of InitLLVM() * make the signature of AddSignalHandler() the same for all platforms * guard behavior changes with NeedsPOSIXUtilitySignalHandling --- clang/tools/driver/driver.cpp | 2 +- .../llvm/Support/CrashRecoveryContext.h | 2 +- llvm/include/llvm/Support/InitLLVM.h | 2 +- llvm/include/llvm/Support/Signals.h | 12 ++---- llvm/lib/Support/CrashRecoveryContext.cpp | 25 +++++++----- llvm/lib/Support/Unix/Signals.inc | 40 ++++++++++++------- llvm/lib/Support/Windows/Signals.inc | 3 +- 7 files changed, 48 insertions(+), 38 deletions(-) diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index a586494cdc8a9..e6cabcc7eb530 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -381,7 +381,7 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { if (!UseNewCC1Process) { TheDriver.CC1Main = ExecuteCC1WithContext; // Ensure the CC1Command actually catches cc1 crashes - llvm::CrashRecoveryContext::Enable(); + llvm::CrashRecoveryContext::Enable(true); } std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args)); diff --git a/llvm/include/llvm/Support/CrashRecoveryContext.h b/llvm/include/llvm/Support/CrashRecoveryContext.h index ffee81dd24587..4abd2d0eedcde 100644 --- a/llvm/include/llvm/Support/CrashRecoveryContext.h +++ b/llvm/include/llvm/Support/CrashRecoveryContext.h @@ -60,7 +60,7 @@ class CrashRecoveryContext { LLVM_ABI void unregisterCleanup(CrashRecoveryContextCleanup *cleanup); /// Enable crash recovery. - LLVM_ABI static void Enable(); + LLVM_ABI static void Enable(bool NeedsPOSIXUtilitySignalHandling = false); /// Disable crash recovery. LLVM_ABI static void Disable(); diff --git a/llvm/include/llvm/Support/InitLLVM.h b/llvm/include/llvm/Support/InitLLVM.h index 02a315790e139..4d513bfd576bb 100644 --- a/llvm/include/llvm/Support/InitLLVM.h +++ b/llvm/include/llvm/Support/InitLLVM.h @@ -37,7 +37,7 @@ class InitLLVM { public: LLVM_ABI InitLLVM(int &Argc, const char **&Argv, bool InstallPipeSignalExitHandler = true, - bool IsClandDriver = false); + bool NeedsPOSIXUtilitySignalHandling = false); InitLLVM(int &Argc, char **&Argv, bool InstallPipeSignalExitHandler = true, bool NeedsPOSIXUtilitySignalHandling = false) : InitLLVM(Argc, const_cast<const char **&>(Argv), diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h index 916d0ed7dea69..d9bff20b85393 100644 --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -99,16 +99,12 @@ using SignalHandlerCallback = void (*)(void *); /// Add a function to be called when an abort/kill signal is delivered to the /// process. The handler can have a cookie passed to it to identify what -/// instance of the handler it is. On Unix systems, the -/// NeedsPOSIXUtilitySignalHandling argument indicates whether POSIX signal -/// handling semantics are followed, so that the signal handler resignals -/// itself to terminate after handling the signal. -#ifdef _WIN32 -LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie); -#else +/// instance of the handler it is. The NeedsPOSIXUtilitySignalHandling +/// argument indicates whether POSIX signal handling semantics are followed, +/// so that the signal handler resignals itself to terminate after handling +/// the signal. LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, bool NeedsPOSIXUtilitySignalHandling = false); -#endif /// This function registers a function to be called when the user "interrupts" /// the program (typically by pressing ctrl-c). When the user interrupts the diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index c6bfa4d0245da..d8318ba6caa35 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -92,7 +92,7 @@ static LLVM_THREAD_LOCAL const CrashRecoveryContext *IsRecoveringFromCrash; } // namespace -static void installExceptionOrSignalHandlers(); +static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling); static void uninstallExceptionOrSignalHandlers(); CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() = default; @@ -137,13 +137,13 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { return CRCI->CRC; } -void CrashRecoveryContext::Enable() { +void CrashRecoveryContext::Enable(bool NeedsPOSIXUtilitySignalHandling) { std::lock_guard<std::mutex> L(getCrashRecoveryContextMutex()); // FIXME: Shouldn't this be a refcount or something? if (gCrashRecoveryEnabled) return; gCrashRecoveryEnabled = true; - installExceptionOrSignalHandlers(); + installExceptionOrSignalHandlers(NeedsPOSIXUtilitySignalHandling); } void CrashRecoveryContext::Disable() { @@ -193,7 +193,7 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { // catches exceptions if they would bubble out from the stack frame with __try / // __except. -static void installExceptionOrSignalHandlers() {} +static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) {} static void uninstallExceptionOrSignalHandlers() {} // We need this function because the call to GetExceptionInformation() can only @@ -309,7 +309,7 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) // non-NULL, valid VEH handles, or NULL. static LLVM_THREAD_LOCAL const void* sCurrentExceptionHandle; -static void installExceptionOrSignalHandlers() { +static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) { // We can set up vectored exception handling now. We will install our // handler as the front of the list, though there's no assurances that // it will remain at the front (another call could install itself before @@ -390,7 +390,7 @@ static void CrashRecoverySignalHandler(int Signal) { const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash(RetCode, Signal); } -static void installExceptionOrSignalHandlers() { +static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) { // Setup the signal handler. struct sigaction Handler; Handler.sa_handler = CrashRecoverySignalHandler; @@ -398,11 +398,14 @@ static void installExceptionOrSignalHandlers() { sigemptyset(&Handler.sa_mask); for (unsigned i = 0; i != NumSignals; ++i) { - struct sigaction act; - sigaction(Signals[i], NULL, &act); - // Don't install signal handler if the disposition of a signal is SIG_IGN. - if (act.sa_handler != SIG_IGN) - sigaction(Signals[i], &Handler, &PrevActions[i]); + if (NeedsPOSIXUtilitySignalHandling) { + // Don't install the new handler if the signal disposition is SIG_IGN. + struct sigaction act; + if (sigaction(Signals[i], NULL, &act) == 0 && act.sa_handler != SIG_IGN) + sigaction(Signals[i], &Handler, &PrevActions[i]); + } else { + sigaction(Signals[i], &Handler, &PrevActions[i]); + } } } diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index d7f1368428694..9de01ab6cf539 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -84,7 +84,8 @@ using namespace llvm; -static void SignalHandler(int Sig, siginfo_t *Info, void *); +static void SignalHandler(int Sig, siginfo_t *Info, void *Context); +static void SignalHandlerTerminate(int Sig, siginfo_t *Info, void *Context); static void InfoSignalHandler(int Sig); // defined below. static void InfoSignalHandlerTerminate(int Sig); // defined below. @@ -319,7 +320,12 @@ static void RegisterHandlers( switch (Kind) { case SignalKind::IsKill: - NewHandler.sa_sigaction = SignalHandler; + if (NeedsPOSIXUtilitySignalHandling) + // If POSIX signal-handling semantics are followed, the signal handler + // resignal itself to terminate after handling the signal. + NewHandler.sa_sigaction = SignalHandlerTerminate; + else + NewHandler.sa_sigaction = SignalHandler; NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK | SA_SIGINFO; break; case SignalKind::IsInfo: @@ -334,12 +340,14 @@ static void RegisterHandlers( } sigemptyset(&NewHandler.sa_mask); - // Install the new handler if the signal disposition isn't SIG_IGN, - // save the old one in RegisteredSignalInfo. - struct sigaction act; - sigaction(Signal, NULL, &act); - if (act.sa_handler != SIG_IGN) + if (NeedsPOSIXUtilitySignalHandling) { + // Don't install the new handler if the signal disposition is SIG_IGN. + struct sigaction act; + if (sigaction(Signal, NULL, &act) == 0 && act.sa_handler != SIG_IGN) + sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA); + } else { sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA); + } RegisteredSignalInfo[Index].SigNo = Signal; ++NumRegisteredSignals; }; @@ -388,7 +396,7 @@ void sys::CleanupOnSignal(uintptr_t Context) { } // The signal handler that runs. -static void SignalHandler(int Sig, siginfo_t *Info, void *) { +static void SignalHandler(int Sig, siginfo_t *Info, void *Context) { // Restore the signal behavior to default, so that the program actually // crashes when we return and the signal reissues. This also ensures that if // we crash in our signal handler that the program will terminate immediately @@ -422,13 +430,6 @@ static void SignalHandler(int Sig, siginfo_t *Info, void *) { // Otherwise if it is a fault (like SEGV) run any handler. llvm::sys::RunSignalHandlers(); - // Resignal if it is a kill signal so that the exit code contains the - // terminating signal number. - if (llvm::is_contained(KillSigs, Sig)) { - raise(Sig); // Execute the default handler. - return; - } - #if defined(__linux__) // Re-raising a signal via `raise` loses the original siginfo. Recent // versions of linux (>= 3.9) support processes sending a signal to itself @@ -446,6 +447,15 @@ static void SignalHandler(int Sig, siginfo_t *Info, void *) { #endif } +static void SignalHandlerTerminate(int Sig, siginfo_t *Info, void *Context) { + SignalHandler(Sig, Info, Context); + + // Resignal if it is a kill signal so that the exit code contains the + // terminating signal number. + if (llvm::is_contained(KillSigs, Sig)) + raise(Sig); // Execute the default handler. +} + static void InfoSignalHandler(int Sig) { SaveAndRestore SaveErrnoDuringASignalHandler(errno); if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction) diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index eec112e5a80f5..d73ad6cda6ddc 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -550,7 +550,8 @@ void llvm::sys::CallOneShotPipeSignalHandler() { /// handler can have a cookie passed to it to identify what instance of the /// handler it is. void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, - void *Cookie) { + void *Cookie, + bool NeedsPOSIXUtilitySignalHandling) insertSignalHandler(FnPtr, Cookie); RegisterHandler(); LeaveCriticalSection(&CriticalSection); >From 4d4bf564d097e986f79bc41de81244c18fe09baf Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Mon, 9 Feb 2026 11:39:08 -0500 Subject: [PATCH 09/10] Fix formatting. --- llvm/lib/Support/CrashRecoveryContext.cpp | 14 +++++++++----- llvm/lib/Support/Windows/Signals.inc | 3 +-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index d8318ba6caa35..cf35fdd9f3aa6 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -92,7 +92,8 @@ static LLVM_THREAD_LOCAL const CrashRecoveryContext *IsRecoveringFromCrash; } // namespace -static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling); +static void +installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling); static void uninstallExceptionOrSignalHandlers(); CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() = default; @@ -193,7 +194,8 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { // catches exceptions if they would bubble out from the stack frame with __try / // __except. -static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) {} +static void +installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) {} static void uninstallExceptionOrSignalHandlers() {} // We need this function because the call to GetExceptionInformation() can only @@ -309,7 +311,8 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) // non-NULL, valid VEH handles, or NULL. static LLVM_THREAD_LOCAL const void* sCurrentExceptionHandle; -static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) { +static void +installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) { // We can set up vectored exception handling now. We will install our // handler as the front of the list, though there's no assurances that // it will remain at the front (another call could install itself before @@ -390,7 +393,8 @@ static void CrashRecoverySignalHandler(int Signal) { const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash(RetCode, Signal); } -static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) { +static void +installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandling) { // Setup the signal handler. struct sigaction Handler; Handler.sa_handler = CrashRecoverySignalHandler; @@ -404,7 +408,7 @@ static void installExceptionOrSignalHandlers(bool NeedsPOSIXUtilitySignalHandlin if (sigaction(Signals[i], NULL, &act) == 0 && act.sa_handler != SIG_IGN) sigaction(Signals[i], &Handler, &PrevActions[i]); } else { - sigaction(Signals[i], &Handler, &PrevActions[i]); + sigaction(Signals[i], &Handler, &PrevActions[i]); } } } diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index d73ad6cda6ddc..4be5a07fe23ce 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -549,8 +549,7 @@ void llvm::sys::CallOneShotPipeSignalHandler() { /// Add a function to be called when a signal is delivered to the process. The /// handler can have a cookie passed to it to identify what instance of the /// handler it is. -void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, - void *Cookie, +void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie, bool NeedsPOSIXUtilitySignalHandling) insertSignalHandler(FnPtr, Cookie); RegisterHandler(); >From 90ec9a5c6ea91f41c2cca7becccf151d16ca71a8 Mon Sep 17 00:00:00 2001 From: Xing Xue <[email protected]> Date: Mon, 9 Feb 2026 12:50:59 -0500 Subject: [PATCH 10/10] Fix formatting (don't understand it though). --- llvm/lib/Support/Windows/Signals.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index 4be5a07fe23ce..a93d3abf6f50d 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -551,9 +551,9 @@ void llvm::sys::CallOneShotPipeSignalHandler() { /// handler it is. void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie, bool NeedsPOSIXUtilitySignalHandling) - insertSignalHandler(FnPtr, Cookie); - RegisterHandler(); - LeaveCriticalSection(&CriticalSection); + insertSignalHandler(FnPtr, Cookie); +RegisterHandler(); +LeaveCriticalSection(&CriticalSection); } static void Cleanup(bool ExecuteSignalHandlers) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
