Revert "Disable exit-on-SIGPIPE in lldb"
This reverts commit 32ce14e55e
.
In post-commit review, Pavel pointed out that there's a simpler way to
ignore SIGPIPE in lldb that doesn't rely on llvm's handlers.
This commit is contained in:
parent
23b7836415
commit
d0bd3fc88b
|
@ -853,16 +853,6 @@ int main(int argc, char const *argv[])
|
||||||
signal(SIGCONT, sigcont_handler);
|
signal(SIGCONT, sigcont_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Occasionally, during test teardown, LLDB writes to a closed pipe.
|
|
||||||
// Sometimes the communication is inherently unreliable, so LLDB tries to
|
|
||||||
// avoid being killed due to SIGPIPE. However, LLVM's default SIGPIPE behavior
|
|
||||||
// is to exit with IO_ERR. Opt LLDB out of that.
|
|
||||||
//
|
|
||||||
// We don't disable LLVM's signal handling entirely because we still want
|
|
||||||
// pretty stack traces, and file cleanup (for when, say, the clang embedded
|
|
||||||
// in LLDB leaves behind temporary objects).
|
|
||||||
llvm::sys::SetPipeSignalFunction(nullptr);
|
|
||||||
|
|
||||||
int exit_code = 0;
|
int exit_code = 0;
|
||||||
// Create a scope for driver so that the driver object will destroy itself
|
// Create a scope for driver so that the driver object will destroy itself
|
||||||
// before SBDebugger::Terminate() is called.
|
// before SBDebugger::Terminate() is called.
|
||||||
|
|
|
@ -84,17 +84,6 @@ namespace sys {
|
||||||
/// function. Note also that the handler may be executed on a different
|
/// function. Note also that the handler may be executed on a different
|
||||||
/// thread on some platforms.
|
/// thread on some platforms.
|
||||||
void SetInfoSignalFunction(void (*Handler)());
|
void SetInfoSignalFunction(void (*Handler)());
|
||||||
|
|
||||||
/// Registers a function to be called when a "pipe" signal is delivered to
|
|
||||||
/// the process.
|
|
||||||
///
|
|
||||||
/// The "pipe" signal typically indicates a failed write to a pipe (SIGPIPE).
|
|
||||||
/// The default installed handler calls `exit(EX_IOERR)`, causing the process
|
|
||||||
/// to immediately exit with an IO error exit code.
|
|
||||||
///
|
|
||||||
/// This function is only applicable on POSIX systems.
|
|
||||||
void SetPipeSignalFunction(void (*Handler)());
|
|
||||||
|
|
||||||
} // End sys namespace
|
} // End sys namespace
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
|
|
@ -82,18 +82,12 @@ using namespace llvm;
|
||||||
static RETSIGTYPE SignalHandler(int Sig); // defined below.
|
static RETSIGTYPE SignalHandler(int Sig); // defined below.
|
||||||
static RETSIGTYPE InfoSignalHandler(int Sig); // defined below.
|
static RETSIGTYPE InfoSignalHandler(int Sig); // defined below.
|
||||||
|
|
||||||
static void DefaultPipeSignalFunction() {
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
using SignalHandlerFunctionType = void (*)();
|
using SignalHandlerFunctionType = void (*)();
|
||||||
/// The function to call if ctrl-c is pressed.
|
/// The function to call if ctrl-c is pressed.
|
||||||
static std::atomic<SignalHandlerFunctionType> InterruptFunction =
|
static std::atomic<SignalHandlerFunctionType> InterruptFunction =
|
||||||
ATOMIC_VAR_INIT(nullptr);
|
ATOMIC_VAR_INIT(nullptr);
|
||||||
static std::atomic<SignalHandlerFunctionType> InfoSignalFunction =
|
static std::atomic<SignalHandlerFunctionType> InfoSignalFunction =
|
||||||
ATOMIC_VAR_INIT(nullptr);
|
ATOMIC_VAR_INIT(nullptr);
|
||||||
static std::atomic<SignalHandlerFunctionType> PipeSignalFunction =
|
|
||||||
ATOMIC_VAR_INIT(DefaultPipeSignalFunction);
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/// Signal-safe removal of files.
|
/// Signal-safe removal of files.
|
||||||
|
@ -369,8 +363,7 @@ static RETSIGTYPE SignalHandler(int Sig) {
|
||||||
|
|
||||||
// Send a special return code that drivers can check for, from sysexits.h.
|
// Send a special return code that drivers can check for, from sysexits.h.
|
||||||
if (Sig == SIGPIPE)
|
if (Sig == SIGPIPE)
|
||||||
if (SignalHandlerFunctionType CurrentPipeFunction = PipeSignalFunction)
|
exit(EX_IOERR);
|
||||||
CurrentPipeFunction();
|
|
||||||
|
|
||||||
raise(Sig); // Execute the default handler.
|
raise(Sig); // Execute the default handler.
|
||||||
return;
|
return;
|
||||||
|
@ -410,11 +403,6 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
|
||||||
RegisterHandlers();
|
RegisterHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm::sys::SetPipeSignalFunction(void (*Handler)()) {
|
|
||||||
PipeSignalFunction.exchange(Handler);
|
|
||||||
RegisterHandlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The public API
|
// The public API
|
||||||
bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
|
bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
|
||||||
std::string* ErrMsg) {
|
std::string* ErrMsg) {
|
||||||
|
|
|
@ -560,9 +560,6 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
|
||||||
// Unimplemented.
|
// Unimplemented.
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm::sys::SetPipeSignalFunction(void (*Handler)()) {
|
|
||||||
// Unimplemented.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a function to be called when a signal is delivered to the process. The
|
/// 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 can have a cookie passed to it to identify what instance of the
|
||||||
|
|
|
@ -58,7 +58,6 @@ add_llvm_unittest(SupportTests
|
||||||
ReverseIterationTest.cpp
|
ReverseIterationTest.cpp
|
||||||
ReplaceFileTest.cpp
|
ReplaceFileTest.cpp
|
||||||
ScaledNumberTest.cpp
|
ScaledNumberTest.cpp
|
||||||
SignalsTest.cpp
|
|
||||||
SourceMgrTest.cpp
|
SourceMgrTest.cpp
|
||||||
SpecialCaseListTest.cpp
|
SpecialCaseListTest.cpp
|
||||||
StringPool.cpp
|
StringPool.cpp
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
//========- unittests/Support/SignalsTest.cpp - Signal handling test =========//
|
|
||||||
//
|
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#endif // !defined(_WIN32)
|
|
||||||
|
|
||||||
#include "llvm/Support/Signals.h"
|
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
TEST(SignalTest, IgnoreMultipleSIGPIPEs) {
|
|
||||||
// Ignore SIGPIPE.
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
|
||||||
|
|
||||||
// Disable exit-on-SIGPIPE.
|
|
||||||
sys::SetPipeSignalFunction(nullptr);
|
|
||||||
|
|
||||||
// Create unidirectional read/write pipes.
|
|
||||||
int fds[2];
|
|
||||||
int err = pipe(fds);
|
|
||||||
if (err != 0)
|
|
||||||
return; // If we can't make pipes, this isn't testing anything.
|
|
||||||
|
|
||||||
// Close the read pipe.
|
|
||||||
close(fds[0]);
|
|
||||||
|
|
||||||
// Attempt to write to the write pipe. Currently we're asserting that the
|
|
||||||
// write fails, which isn't great.
|
|
||||||
//
|
|
||||||
// What we really want is a death test that checks that this block exits
|
|
||||||
// with a special exit "success" code, as opposed to unexpectedly exiting due
|
|
||||||
// to a kill-by-SIGNAL or due to the default SIGPIPE handler.
|
|
||||||
//
|
|
||||||
// Unfortunately llvm's unit tests aren't set up to support death tests well.
|
|
||||||
// For one, death tests are flaky in a multithreaded context. And sigactions
|
|
||||||
// inherited from llvm-lit interfere with what's being tested.
|
|
||||||
const void *buf = (const void *)&fds;
|
|
||||||
err = write(fds[1], buf, 1);
|
|
||||||
ASSERT_EQ(err, -1);
|
|
||||||
err = write(fds[1], buf, 1);
|
|
||||||
ASSERT_EQ(err, -1);
|
|
||||||
}
|
|
||||||
#endif // !defined(_WIN32)
|
|
Loading…
Reference in New Issue