//===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
// Unix signals occurring while your program is running.
//
//===----------------------------------------------------------------------===//
//
// This file is extremely careful to only do signal-safe things while in a
// signal handler. In particular, memory allocation and acquiring a mutex
// while in a signal handler should never occur. ManagedStatic isn't usable from
// a signal handler for 2 reasons:
//
//  1. Creating a new one allocates.
//  2. The signal handler could fire while llvm_shutdown is being processed, in
//     which case the ManagedStatic is in an unknown state because it could
//     already have been destroyed, or be in the process of being destroyed.
//
// Modifying the behavior of the signal handlers (such as registering new ones)
// can acquire a mutex, but all this guarantees is that the signal handler
// behavior is only modified by one thread at a time. A signal handler can still
// fire while this occurs!
//
// Adding work to a signal handler requires lock-freedom (and assume atomics are
// always lock-free) because the signal handler could fire while new work is
// being added.
//
//===----------------------------------------------------------------------===//

#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/ExitCodes.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>
#ifdef HAVE_BACKTRACE
# include BACKTRACE_HEADER         // For backtrace().
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if HAVE_MACH_MACH_H
#include <mach/mach.h>
#endif
#if HAVE_LINK_H
#include <link.h>
#endif
#ifdef HAVE__UNWIND_BACKTRACE
// FIXME: We should be able to use <unwind.h> for any target that has an
// _Unwind_Backtrace function, but on FreeBSD the configure test passes
// despite the function not existing, and on Android, <unwind.h> conflicts
// with <link.h>.
#ifdef __GLIBC__
#include <unwind.h>
#else
#undef HAVE__UNWIND_BACKTRACE
#endif
#endif

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.
static std::atomic<SignalHandlerFunctionType> InterruptFunction =
    ATOMIC_VAR_INIT(nullptr);
static std::atomic<SignalHandlerFunctionType> InfoSignalFunction =
    ATOMIC_VAR_INIT(nullptr);
/// The function to call on SIGPIPE (one-time use only).
static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction =
    ATOMIC_VAR_INIT(nullptr);

namespace {
/// Signal-safe removal of files.
/// Inserting and erasing from the list isn't signal-safe, but removal of files
/// themselves is signal-safe. Memory is freed when the head is freed, deletion
/// is therefore not signal-safe either.
class FileToRemoveList {
  std::atomic<char *> Filename = ATOMIC_VAR_INIT(nullptr);
  std::atomic<FileToRemoveList *> Next = ATOMIC_VAR_INIT(nullptr);

  FileToRemoveList() = default;
  // Not signal-safe.
  FileToRemoveList(const std::string &str) : Filename(strdup(str.c_str())) {}

public:
  // Not signal-safe.
  ~FileToRemoveList() {
    if (FileToRemoveList *N = Next.exchange(nullptr))
      delete N;
    if (char *F = Filename.exchange(nullptr))
      free(F);
  }

  // Not signal-safe.
  static void insert(std::atomic<FileToRemoveList *> &Head,
                     const std::string &Filename) {
    // Insert the new file at the end of the list.
    FileToRemoveList *NewHead = new FileToRemoveList(Filename);
    std::atomic<FileToRemoveList *> *InsertionPoint = &Head;
    FileToRemoveList *OldHead = nullptr;
    while (!InsertionPoint->compare_exchange_strong(OldHead, NewHead)) {
      InsertionPoint = &OldHead->Next;
      OldHead = nullptr;
    }
  }

  // Not signal-safe.
  static void erase(std::atomic<FileToRemoveList *> &Head,
                    const std::string &Filename) {
    // Use a lock to avoid concurrent erase: the comparison would access
    // free'd memory.
    static ManagedStatic<sys::SmartMutex<true>> Lock;
    sys::SmartScopedLock<true> Writer(*Lock);

    for (FileToRemoveList *Current = Head.load(); Current;
         Current = Current->Next.load()) {
      if (char *OldFilename = Current->Filename.load()) {
        if (OldFilename != Filename)
          continue;
        // Leave an empty filename.
        OldFilename = Current->Filename.exchange(nullptr);
        // The filename might have become null between the time we
        // compared it and we exchanged it.
        if (OldFilename)
          free(OldFilename);
      }
    }
  }

  // Signal-safe.
  static void removeAllFiles(std::atomic<FileToRemoveList *> &Head) {
    // If cleanup were to occur while we're removing files we'd have a bad time.
    // Make sure we're OK by preventing cleanup from doing anything while we're
    // removing files. If cleanup races with us and we win we'll have a leak,
    // but we won't crash.
    FileToRemoveList *OldHead = Head.exchange(nullptr);

    for (FileToRemoveList *currentFile = OldHead; currentFile;
         currentFile = currentFile->Next.load()) {
      // If erasing was occuring while we're trying to remove files we'd look
      // at free'd data. Take away the path and put it back when done.
      if (char *path = currentFile->Filename.exchange(nullptr)) {
        // Get the status so we can determine if it's a file or directory. If we
        // can't stat the file, ignore it.
        struct stat buf;
        if (stat(path, &buf) != 0)
          continue;

        // If this is not a regular file, ignore it. We want to prevent removal
        // of special files like /dev/null, even if the compiler is being run
        // with the super-user permissions.
        if (!S_ISREG(buf.st_mode))
          continue;

        // Otherwise, remove the file. We ignore any errors here as there is
        // nothing else we can do.
        unlink(path);

        // We're done removing the file, erasing can safely proceed.
        currentFile->Filename.exchange(path);
      }
    }

    // We're done removing files, cleanup can safely proceed.
    Head.exchange(OldHead);
  }
};
static std::atomic<FileToRemoveList *> FilesToRemove = ATOMIC_VAR_INIT(nullptr);

/// Clean up the list in a signal-friendly manner.
/// Recall that signals can fire during llvm_shutdown. If this occurs we should
/// either clean something up or nothing at all, but we shouldn't crash!
struct FilesToRemoveCleanup {
  // Not signal-safe.
  ~FilesToRemoveCleanup() {
    FileToRemoveList *Head = FilesToRemove.exchange(nullptr);
    if (Head)
      delete Head;
  }
};
} // namespace

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.
static const int IntSigs[] = {
  SIGHUP, SIGINT, SIGTERM, SIGUSR2
};

/// 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
  , SIGSYS
#endif
#ifdef SIGXCPU
  , SIGXCPU
#endif
#ifdef SIGXFSZ
  , SIGXFSZ
#endif
#ifdef SIGEMT
  , SIGEMT
#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) + 1 /* SIGPIPE */;


static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0);
static struct {
  struct sigaction SA;
  int SigNo;
} RegisteredSignalInfo[NumSigs];

#if defined(HAVE_SIGALTSTACK)
// Hold onto both the old and new alternate signal stack so that it's not
// reported as a leak. We don't make any attempt to remove our alt signal
// stack if we remove our signal handlers; that can't be done reliably if
// someone else is also trying to do the same thing.
static stack_t OldAltStack;
LLVM_ATTRIBUTE_USED static void *NewAltStackPointer;

static void CreateSigAltStack() {
  const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;

  // If we're executing on the alternate stack, or we already have an alternate
  // signal stack that we're happy with, there's nothing for us to do. Don't
  // reduce the size, some other part of the process might need a larger stack
  // than we do.
  if (sigaltstack(nullptr, &OldAltStack) != 0 ||
      OldAltStack.ss_flags & SS_ONSTACK ||
      (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
    return;

  stack_t AltStack = {};
  AltStack.ss_sp = static_cast<char *>(safe_malloc(AltStackSize));
  NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
  AltStack.ss_size = AltStackSize;
  if (sigaltstack(&AltStack, &OldAltStack) != 0)
    free(AltStack.ss_sp);
}
#else
static void CreateSigAltStack() {}
#endif

static void RegisterHandlers() { // Not signal-safe.
  // The mutex prevents other threads from registering handlers while we're
  // doing it. We also have to protect the handlers and their count because
  // a signal handler could fire while we're registeting handlers.
  static ManagedStatic<sys::SmartMutex<true>> SignalHandlerRegistrationMutex;
  sys::SmartScopedLock<true> Guard(*SignalHandlerRegistrationMutex);

  // If the handlers are already registered, we're done.
  if (NumRegisteredSignals.load() != 0)
    return;

  // Create an alternate stack for signal handling. This is necessary for us to
  // be able to reliably handle signals due to stack overflow.
  CreateSigAltStack();

  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;

    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.
    sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
    RegisteredSignalInfo[Index].SigNo = Signal;
    ++NumRegisteredSignals;
  };

  for (auto S : IntSigs)
    registerHandler(S, SignalKind::IsKill);
  for (auto S : KillSigs)
    registerHandler(S, SignalKind::IsKill);
  if (OneShotPipeSignalFunction)
    registerHandler(SIGPIPE, SignalKind::IsKill);
  for (auto S : InfoSigs)
    registerHandler(S, SignalKind::IsInfo);
}

void sys::unregisterHandlers() {
  // Restore all of the signal handlers to how they were before we showed up.
  for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
    sigaction(RegisteredSignalInfo[i].SigNo,
              &RegisteredSignalInfo[i].SA, nullptr);
    --NumRegisteredSignals;
  }
}

/// Process the FilesToRemove list.
static void RemoveFilesToRemove() {
  FileToRemoveList::removeAllFiles(FilesToRemove);
}

void sys::CleanupOnSignal(uintptr_t Context) {
  int Sig = (int)Context;

  if (llvm::is_contained(InfoSigs, Sig)) {
    InfoSignalHandler(Sig);
    return;
  }

  RemoveFilesToRemove();

  if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE)
    return;

  llvm::sys::RunSignalHandlers();
}

// The signal handler that runs.
static RETSIGTYPE SignalHandler(int Sig) {
  // Restore the signal behavior to default, so that the program actually
  // crashes when we return and the signal reissues.  This also ensures that if
  // we crash in our signal handler that the program will terminate immediately
  // instead of recursing in the signal handler.
  sys::unregisterHandlers();

  // Unmask all potentially blocked kill signals.
  sigset_t SigMask;
  sigfillset(&SigMask);
  sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);

  {
    RemoveFilesToRemove();

    if (Sig == SIGPIPE)
      if (auto OldOneShotPipeFunction =
              OneShotPipeSignalFunction.exchange(nullptr))
        return OldOneShotPipeFunction();

    bool IsIntSig = llvm::is_contained(IntSigs, Sig);
    if (IsIntSig)
      if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr))
        return OldInterruptFunction();

    if (Sig == SIGPIPE || IsIntSig) {
      raise(Sig); // Execute the default handler.
      return;
    }
  }

  // Otherwise if it is a fault (like SEGV) run any handler.
  llvm::sys::RunSignalHandlers();

#ifdef __s390__
  // On S/390, certain signals are delivered with PSW Address pointing to
  // *after* the faulting instruction.  Simply returning from the signal
  // handler would continue execution after that point, instead of
  // re-raising the signal.  Raise the signal manually in those cases.
  if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
    raise(Sig);
#endif
}

static RETSIGTYPE InfoSignalHandler(int Sig) {
  SaveAndRestore<int> SaveErrnoDuringASignalHandler(errno);
  if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
    CurrentInfoFunction();
}

void llvm::sys::RunInterruptHandlers() {
  RemoveFilesToRemove();
}

void llvm::sys::SetInterruptFunction(void (*IF)()) {
  InterruptFunction.exchange(IF);
  RegisterHandlers();
}

void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
  InfoSignalFunction.exchange(Handler);
  RegisterHandlers();
}

void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
  OneShotPipeSignalFunction.exchange(Handler);
  RegisterHandlers();
}

void llvm::sys::DefaultOneShotPipeSignalHandler() {
  // Send a special return code that drivers can check for, from sysexits.h.
  exit(EX_IOERR);
}

// The public API
bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
                                   std::string* ErrMsg) {
  // Ensure that cleanup will occur as soon as one file is added.
  static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
  *FilesToRemoveCleanup;
  FileToRemoveList::insert(FilesToRemove, Filename.str());
  RegisterHandlers();
  return false;
}

// The public API
void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {
  FileToRemoveList::erase(FilesToRemove, Filename.str());
}

/// 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 it is.
void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr,
                                 void *Cookie) { // Signal-safe.
  insertSignalHandler(FnPtr, Cookie);
  RegisterHandlers();
}

#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H &&    \
    (defined(__linux__) || defined(__FreeBSD__) ||                             \
     defined(__FreeBSD_kernel__) || defined(__NetBSD__))
struct DlIteratePhdrData {
  void **StackTrace;
  int depth;
  bool first;
  const char **modules;
  intptr_t *offsets;
  const char *main_exec_name;
};

static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
  DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
  const char *name = data->first ? data->main_exec_name : info->dlpi_name;
  data->first = false;
  for (int i = 0; i < info->dlpi_phnum; i++) {
    const auto *phdr = &info->dlpi_phdr[i];
    if (phdr->p_type != PT_LOAD)
      continue;
    intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
    intptr_t end = beg + phdr->p_memsz;
    for (int j = 0; j < data->depth; j++) {
      if (data->modules[j])
        continue;
      intptr_t addr = (intptr_t)data->StackTrace[j];
      if (beg <= addr && addr < end) {
        data->modules[j] = name;
        data->offsets[j] = addr - info->dlpi_addr;
      }
    }
  }
  return 0;
}

/// If this is an ELF platform, we can find all loaded modules and their virtual
/// addresses with dl_iterate_phdr.
static bool findModulesAndOffsets(void **StackTrace, int Depth,
                                  const char **Modules, intptr_t *Offsets,
                                  const char *MainExecutableName,
                                  StringSaver &StrPool) {
  DlIteratePhdrData data = {StackTrace, Depth,   true,
                            Modules,    Offsets, MainExecutableName};
  dl_iterate_phdr(dl_iterate_phdr_cb, &data);
  return true;
}
#else
/// This platform does not have dl_iterate_phdr, so we do not yet know how to
/// find all loaded DSOs.
static bool findModulesAndOffsets(void **StackTrace, int Depth,
                                  const char **Modules, intptr_t *Offsets,
                                  const char *MainExecutableName,
                                  StringSaver &StrPool) {
  return false;
}
#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...

#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
static int unwindBacktrace(void **StackTrace, int MaxEntries) {
  if (MaxEntries < 0)
    return 0;

  // Skip the first frame ('unwindBacktrace' itself).
  int Entries = -1;

  auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
    // Apparently we need to detect reaching the end of the stack ourselves.
    void *IP = (void *)_Unwind_GetIP(Context);
    if (!IP)
      return _URC_END_OF_STACK;

    assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
    if (Entries >= 0)
      StackTrace[Entries] = IP;

    if (++Entries == MaxEntries)
      return _URC_END_OF_STACK;
    return _URC_NO_REASON;
  };

  _Unwind_Backtrace(
      [](_Unwind_Context *Context, void *Handler) {
        return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
      },
      static_cast<void *>(&HandleFrame));
  return std::max(Entries, 0);
}
#endif

// In the case of a program crash or fault, print out a stack trace so that the
// user has an indication of why and where we died.
//
// On glibc systems we have the 'backtrace' function, which works nicely, but
// doesn't demangle symbols.
void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
#if ENABLE_BACKTRACES
  static void *StackTrace[256];
  int depth = 0;
#if defined(HAVE_BACKTRACE)
  // Use backtrace() to output a backtrace on Linux systems with glibc.
  if (!depth)
    depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
#endif
#if defined(HAVE__UNWIND_BACKTRACE)
  // Try _Unwind_Backtrace() if backtrace() failed.
  if (!depth)
    depth = unwindBacktrace(StackTrace,
                        static_cast<int>(array_lengthof(StackTrace)));
#endif
  if (!depth)
    return;
  // If "Depth" is not provided by the caller, use the return value of
  // backtrace() for printing a symbolized stack trace.
  if (!Depth)
    Depth = depth;
  if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
    return;
  OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
        "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
        "to it):\n";
#if HAVE_DLFCN_H && HAVE_DLADDR
  int width = 0;
  for (int i = 0; i < depth; ++i) {
    Dl_info dlinfo;
    dladdr(StackTrace[i], &dlinfo);
    const char* name = strrchr(dlinfo.dli_fname, '/');

    int nwidth;
    if (!name) nwidth = strlen(dlinfo.dli_fname);
    else       nwidth = strlen(name) - 1;

    if (nwidth > width) width = nwidth;
  }

  for (int i = 0; i < depth; ++i) {
    Dl_info dlinfo;
    dladdr(StackTrace[i], &dlinfo);

    OS << format("%-2d", i);

    const char* name = strrchr(dlinfo.dli_fname, '/');
    if (!name) OS << format(" %-*s", width, dlinfo.dli_fname);
    else       OS << format(" %-*s", width, name+1);

    OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2,
                 (unsigned long)StackTrace[i]);

    if (dlinfo.dli_sname != nullptr) {
      OS << ' ';
      int res;
      char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
      if (!d) OS << dlinfo.dli_sname;
      else    OS << d;
      free(d);

      OS << format(" + %tu", (static_cast<const char*>(StackTrace[i])-
                              static_cast<const char*>(dlinfo.dli_saddr)));
    }
    OS << '\n';
  }
#elif defined(HAVE_BACKTRACE)
  backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
#endif
#endif
}

static void PrintStackTraceSignalHandler(void *) {
  sys::PrintStackTrace(llvm::errs());
}

void llvm::sys::DisableSystemDialogsOnCrash() {}

/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit.
void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
                                             bool DisableCrashReporting) {
  ::Argv0 = Argv0;

  AddSignalHandler(PrintStackTraceSignalHandler, nullptr);

#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
  // Environment variable to disable any kind of crash dialog.
  if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
    mach_port_t self = mach_task_self();

    exception_mask_t mask = EXC_MASK_CRASH;

    kern_return_t ret = task_set_exception_ports(self,
                             mask,
                             MACH_PORT_NULL,
                             EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
                             THREAD_STATE_NONE);
    (void)ret;
  }
#endif
}
