From 6c84ffbf5fd9d50995eee0a8fbf9efafe08790d7 Mon Sep 17 00:00:00 2001 From: Adrian McCarthy Date: Wed, 20 Sep 2017 18:09:39 +0000 Subject: [PATCH] Fix the SIGINT handlers 1. Fix a data race (g_interrupt_sent flag usage was not thread safe, signals can be handled on arbitrary threads) 2. exit() is not signal-safe, replaced it with the signal-safe equivalent _exit() (This differs from the patch on Phabrictor because I had to add `#include ` to get the definition of `std::atomic_flag`.) patch by lemo Differential Revision: https://reviews.llvm.org/D37926 llvm-svn: 313785 --- lldb/tools/driver/Driver.cpp | 10 +++++----- lldb/tools/lldb-mi/MIDriverMain.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 102ba775da91f..7e1dec7a34fad 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -9,6 +9,7 @@ #include "Driver.h" +#include #include #include #include @@ -1177,17 +1178,16 @@ void sigwinch_handler(int signo) { } void sigint_handler(int signo) { - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; if (g_driver) { - if (!g_interrupt_sent) { - g_interrupt_sent = true; + if (!g_interrupt_sent.test_and_set()) { g_driver->GetDebugger().DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); return; } } - exit(signo); + _exit(signo); } void sigtstp_handler(int signo) { diff --git a/lldb/tools/lldb-mi/MIDriverMain.cpp b/lldb/tools/lldb-mi/MIDriverMain.cpp index be01f1d977901..eda67782ad677 100644 --- a/lldb/tools/lldb-mi/MIDriverMain.cpp +++ b/lldb/tools/lldb-mi/MIDriverMain.cpp @@ -33,6 +33,7 @@ // Third party headers: #include "lldb/API/SBHostOS.h" +#include #include #include @@ -72,14 +73,13 @@ void sigint_handler(int vSigno) { #ifdef _WIN32 // Restore handler as it is not persistent on Windows signal(SIGINT, sigint_handler); #endif - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance(); lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger(); if (pDebugger != nullptr) { - if (!g_interrupt_sent) { - g_interrupt_sent = true; + if (!g_interrupt_sent.test_and_set()) { pDebugger->DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); } }