Author: Jonas Devlieghere Date: 2026-05-08T23:37:16-05:00 New Revision: 5d1a9befd5144cf63daf6879f9bdc171c4693c78
URL: https://github.com/llvm/llvm-project/commit/5d1a9befd5144cf63daf6879f9bdc171c4693c78 DIFF: https://github.com/llvm/llvm-project/commit/5d1a9befd5144cf63daf6879f9bdc171c4693c78.diff LOG: Revert "Revert "[lldb] Handle SIGINT via the MainLoop signal thread (on POSIX…" This reverts commit 0ad1bc96429863fe9fa65706df9a86cec649bf60. Added: Modified: lldb/tools/driver/Driver.cpp Removed: ################################################################################ diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index d47d3daf1c3fc..e58286f9ff41e 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -43,6 +43,9 @@ #include <clocale> #include <csignal> #include <future> +#ifndef _WIN32 +#include <pthread.h> +#endif #include <string> #include <thread> #include <utility> @@ -651,11 +654,10 @@ void Driver::UpdateWindowSize() { } } -void sigint_handler(int signo) { #ifdef _WIN32 +void sigint_handler(int signo) { // Restore handler as it is not persistent on Windows. signal(SIGINT, sigint_handler); -#endif static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; if (g_driver != nullptr) { @@ -668,6 +670,7 @@ void sigint_handler(int signo) { _exit(signo); } +#endif static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) { std::string usage_str = tool_name.str() + " [options]"; @@ -781,15 +784,64 @@ int main(int argc, char const *argv[]) { // Setup LLDB signal handlers once the debugger has been initialized. SBDebugger::PrintDiagnosticsOnError(); - // FIXME: Migrate the SIGINT handler to be handled by the signal loop below. +#ifdef _WIN32 signal(SIGINT, sigint_handler); -#if !defined(_WIN32) +#else signal(SIGPIPE, SIG_IGN); + // Capture the main thread's id so the signal thread can target it. + pthread_t main_thread = pthread_self(); + + // Set when the signal thread sends itself a SIGINT to wake the main thread. + // The next callback invocation observes this flag and skips the work. A + // plain bool is sufficient because the callback only ever runs on the + // signal thread; it lives outside the lambda because MainLoopPosix copies + // the callback on every dispatch, which would discard in-lambda state. + bool skip_next_sigint = false; + // Handle signals in a MainLoop running on a separate thread. MainLoop signal_loop; Status signal_status; + auto sigint_handler = signal_loop.RegisterSignal( + SIGINT, + [&, main_thread](MainLoopBase &) { + // Skip the self-sent wakeup SIGINT queued at the end of the previous + // invocation. + if (std::exchange(skip_next_sigint, false)) + return; + + // Temporarily restore the default disposition so that a second SIGINT + // delivered while DispatchInputInterrupt is running hard-terminates + // the process. This preserves the "double Ctrl-C to force exit" + // escape hatch users rely on when the debugger is unresponsive. + struct sigaction old_action; + struct sigaction new_action = {}; + new_action.sa_handler = SIG_DFL; + sigemptyset(&new_action.sa_mask); + + int ret = sigaction(SIGINT, &new_action, &old_action); + UNUSED_IF_ASSERT_DISABLED(ret); + assert(ret == 0 && "sigaction failed"); + + if (g_driver) + g_driver->GetDebugger().DispatchInputInterrupt(); + + ret = sigaction(SIGINT, &old_action, nullptr); + UNUSED_IF_ASSERT_DISABLED(ret); + assert(ret == 0 && "sigaction failed"); + + // Wake the main thread so any blocking syscall (e.g. the Python REPL + // waiting on input or sleeping) returns with EINTR. This lets Python + // observe the pending interrupt queued by DispatchInputInterrupt and + // raise KeyboardInterrupt. Flag the resulting callback invocation so + // it's skipped rather than re-running DispatchInputInterrupt. + skip_next_sigint = true; + pthread_kill(main_thread, SIGINT); + }, + signal_status); + assert(sigint_handler && signal_status.Success()); + auto sigwinch_handler = signal_loop.RegisterSignal( SIGWINCH, [&](MainLoopBase &) { _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
