diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
commit | 54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch) | |
tree | 4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/Support/Unix/Signals.inc | |
parent | 35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff) | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (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.inc | 81 |
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'; } |