aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support/Unix/Signals.inc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-21 18:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-21 18:13:02 +0000
commit54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch)
tree4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/Support/Unix/Signals.inc
parent35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff)
parente6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff)
Merge llvm trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes: svn path=/projects/clang900-import/; revision=351344
Diffstat (limited to 'contrib/llvm/lib/Support/Unix/Signals.inc')
-rw-r--r--contrib/llvm/lib/Support/Unix/Signals.inc81
1 files changed, 58 insertions, 23 deletions
diff --git a/contrib/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm/lib/Support/Unix/Signals.inc
index ad88d5e96906..634c16aa36c7 100644
--- a/contrib/llvm/lib/Support/Unix/Signals.inc
+++ b/contrib/llvm/lib/Support/Unix/Signals.inc
@@ -1,9 +1,8 @@
//===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -43,6 +42,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/UniqueLock.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -81,10 +81,13 @@
using namespace llvm;
static RETSIGTYPE SignalHandler(int Sig); // defined below.
+static RETSIGTYPE InfoSignalHandler(int Sig); // defined below.
+using SignalHandlerFunctionType = void (*)();
/// The function to call if ctrl-c is pressed.
-using InterruptFunctionType = void (*)();
-static std::atomic<InterruptFunctionType> InterruptFunction =
+static std::atomic<SignalHandlerFunctionType> InterruptFunction =
+ ATOMIC_VAR_INIT(nullptr);
+static std::atomic<SignalHandlerFunctionType> InfoSignalFunction =
ATOMIC_VAR_INIT(nullptr);
namespace {
@@ -200,15 +203,15 @@ struct FilesToRemoveCleanup {
static StringRef Argv0;
-// Signals that represent requested termination. There's no bug or failure, or
-// if there is, it's not our direct responsibility. For whatever reason, our
-// continued execution is no longer desirable.
+/// Signals that represent requested termination. There's no bug or failure, or
+/// if there is, it's not our direct responsibility. For whatever reason, our
+/// continued execution is no longer desirable.
static const int IntSigs[] = {
- SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
+ SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR2
};
-// Signals that represent that we have a bug, and our prompt termination has
-// been ordered.
+/// Signals that represent that we have a bug, and our prompt termination has
+/// been ordered.
static const int KillSigs[] = {
SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT
#ifdef SIGSYS
@@ -225,11 +228,24 @@ static const int KillSigs[] = {
#endif
};
+/// Signals that represent requests for status.
+static const int InfoSigs[] = {
+ SIGUSR1
+#ifdef SIGINFO
+ , SIGINFO
+#endif
+};
+
+static const size_t NumSigs =
+ array_lengthof(IntSigs) + array_lengthof(KillSigs) +
+ array_lengthof(InfoSigs);
+
+
static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0);
static struct {
struct sigaction SA;
int SigNo;
-} RegisteredSignalInfo[array_lengthof(IntSigs) + array_lengthof(KillSigs)];
+} RegisteredSignalInfo[NumSigs];
#if defined(HAVE_SIGALTSTACK)
// Hold onto both the old and new alternate signal stack so that it's not
@@ -277,15 +293,24 @@ static void RegisterHandlers() { // Not signal-safe.
// be able to reliably handle signals due to stack overflow.
CreateSigAltStack();
- auto registerHandler = [&](int Signal) {
+ enum class SignalKind { IsKill, IsInfo };
+ auto registerHandler = [&](int Signal, SignalKind Kind) {
unsigned Index = NumRegisteredSignals.load();
assert(Index < array_lengthof(RegisteredSignalInfo) &&
"Out of space for signal handlers!");
struct sigaction NewHandler;
- NewHandler.sa_handler = SignalHandler;
- NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK;
+ switch (Kind) {
+ case SignalKind::IsKill:
+ NewHandler.sa_handler = SignalHandler;
+ NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK;
+ break;
+ case SignalKind::IsInfo:
+ NewHandler.sa_handler = InfoSignalHandler;
+ NewHandler.sa_flags = SA_ONSTACK;
+ break;
+ }
sigemptyset(&NewHandler.sa_mask);
// Install the new handler, save the old one in RegisteredSignalInfo.
@@ -295,9 +320,11 @@ static void RegisterHandlers() { // Not signal-safe.
};
for (auto S : IntSigs)
- registerHandler(S);
+ registerHandler(S, SignalKind::IsKill);
for (auto S : KillSigs)
- registerHandler(S);
+ registerHandler(S, SignalKind::IsKill);
+ for (auto S : InfoSigs)
+ registerHandler(S, SignalKind::IsInfo);
}
static void UnregisterHandlers() {
@@ -357,6 +384,12 @@ static RETSIGTYPE SignalHandler(int Sig) {
#endif
}
+static RETSIGTYPE InfoSignalHandler(int Sig) {
+ SaveAndRestore<int> SaveErrnoDuringASignalHandler(errno);
+ if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
+ CurrentInfoFunction();
+}
+
void llvm::sys::RunInterruptHandlers() {
RemoveFilesToRemove();
}
@@ -366,6 +399,11 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) {
RegisterHandlers();
}
+void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
+ InfoSignalFunction.exchange(Handler);
+ RegisterHandlers();
+}
+
// The public API
bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
std::string* ErrMsg) {
@@ -540,11 +578,8 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
else OS << d;
free(d);
- // FIXME: When we move to C++11, use %t length modifier. It's not in
- // C++03 and causes gcc to issue warnings. Losing the upper 32 bits of
- // the stack offset for a stack dump isn't likely to cause any problems.
- OS << format(" + %u",(unsigned)((char*)StackTrace[i]-
- (char*)dlinfo.dli_saddr));
+ OS << format(" + %tu", (static_cast<const char*>(StackTrace[i])-
+ static_cast<const char*>(dlinfo.dli_saddr)));
}
OS << '\n';
}