//
// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "absl/debugging/failure_signal_handler.h"

#include "absl/base/config.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <sched.h>
#include <unistd.h>
#endif

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif

#ifdef ABSL_HAVE_MMAP
#include <sys/mman.h>
#endif

#include <algorithm>
#include <atomic>
#include <cerrno>
#include <csignal>
#include <cstdio>
#include <cstring>
#include <ctime>

#include "absl/base/attributes.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/debugging/internal/examine_stack.h"
#include "absl/debugging/stacktrace.h"

#ifndef _WIN32
#define ABSL_HAVE_SIGACTION
// Apple WatchOS and TVOS don't allow sigaltstack
// Apple macOS has sigaltstack, but using it makes backtrace() unusable.
#if !(defined(TARGET_OS_OSX) && TARGET_OS_OSX) &&     \
    !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \
    !(defined(TARGET_OS_TV) && TARGET_OS_TV) && !defined(__QNX__)
#define ABSL_HAVE_SIGALTSTACK
#endif
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN

ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options;

// Resets the signal handler for signo to the default action for that
// signal, then raises the signal.
static void RaiseToDefaultHandler(int signo) {
  signal(signo, SIG_DFL);
  raise(signo);
}

struct FailureSignalData {
  const int signo;
  const char* const as_string;
#ifdef ABSL_HAVE_SIGACTION
  struct sigaction previous_action;
  // StructSigaction is used to silence -Wmissing-field-initializers.
  using StructSigaction = struct sigaction;
  #define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction()
#else
  void (*previous_handler)(int);
  #define FSD_PREVIOUS_INIT SIG_DFL
#endif
};

ABSL_CONST_INIT static FailureSignalData failure_signal_data[] = {
    {SIGSEGV, "SIGSEGV", FSD_PREVIOUS_INIT},
    {SIGILL, "SIGILL", FSD_PREVIOUS_INIT},
    {SIGFPE, "SIGFPE", FSD_PREVIOUS_INIT},
    {SIGABRT, "SIGABRT", FSD_PREVIOUS_INIT},
    {SIGTERM, "SIGTERM", FSD_PREVIOUS_INIT},
#ifndef _WIN32
    {SIGBUS, "SIGBUS", FSD_PREVIOUS_INIT},
    {SIGTRAP, "SIGTRAP", FSD_PREVIOUS_INIT},
#endif
};

#undef FSD_PREVIOUS_INIT

static void RaiseToPreviousHandler(int signo) {
  // Search for the previous handler.
  for (const auto& it : failure_signal_data) {
    if (it.signo == signo) {
#ifdef ABSL_HAVE_SIGACTION
      sigaction(signo, &it.previous_action, nullptr);
#else
      signal(signo, it.previous_handler);
#endif
      raise(signo);
      return;
    }
  }

  // Not found, use the default handler.
  RaiseToDefaultHandler(signo);
}

namespace debugging_internal {

const char* FailureSignalToString(int signo) {
  for (const auto& it : failure_signal_data) {
    if (it.signo == signo) {
      return it.as_string;
    }
  }
  return "";
}

}  // namespace debugging_internal

#ifdef ABSL_HAVE_SIGALTSTACK

static bool SetupAlternateStackOnce() {
#if defined(__wasm__) || defined (__asjms__)
  const size_t page_mask = getpagesize() - 1;
#else
  const size_t page_mask = static_cast<size_t>(sysconf(_SC_PAGESIZE)) - 1;
#endif
  size_t stack_size =
      (std::max<size_t>(SIGSTKSZ, 65536) + page_mask) & ~page_mask;
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
    defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
  // Account for sanitizer instrumentation requiring additional stack space.
  stack_size *= 5;
#endif

  stack_t sigstk;
  memset(&sigstk, 0, sizeof(sigstk));
  sigstk.ss_size = stack_size;

#ifdef ABSL_HAVE_MMAP
#ifndef MAP_STACK
#define MAP_STACK 0
#endif
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
#endif
  sigstk.ss_sp = mmap(nullptr, sigstk.ss_size, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  if (sigstk.ss_sp == MAP_FAILED) {
    ABSL_RAW_LOG(FATAL, "mmap() for alternate signal stack failed");
  }
#else
  sigstk.ss_sp = malloc(sigstk.ss_size);
  if (sigstk.ss_sp == nullptr) {
    ABSL_RAW_LOG(FATAL, "malloc() for alternate signal stack failed");
  }
#endif

  if (sigaltstack(&sigstk, nullptr) != 0) {
    ABSL_RAW_LOG(FATAL, "sigaltstack() failed with errno=%d", errno);
  }
  return true;
}

#endif

#ifdef ABSL_HAVE_SIGACTION

// Sets up an alternate stack for signal handlers once.
// Returns the appropriate flag for sig_action.sa_flags
// if the system supports using an alternate stack.
static int MaybeSetupAlternateStack() {
#ifdef ABSL_HAVE_SIGALTSTACK
  ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce();
  return SA_ONSTACK;
#else
  return 0;
#endif
}

static void InstallOneFailureHandler(FailureSignalData* data,
                                     void (*handler)(int, siginfo_t*, void*)) {
  struct sigaction act;
  memset(&act, 0, sizeof(act));
  sigemptyset(&act.sa_mask);
  act.sa_flags |= SA_SIGINFO;
  // SA_NODEFER is required to handle SIGABRT from
  // ImmediateAbortSignalHandler().
  act.sa_flags |= SA_NODEFER;
  if (fsh_options.use_alternate_stack) {
    act.sa_flags |= MaybeSetupAlternateStack();
  }
  act.sa_sigaction = handler;
  ABSL_RAW_CHECK(sigaction(data->signo, &act, &data->previous_action) == 0,
                 "sigaction() failed");
}

#else

static void InstallOneFailureHandler(FailureSignalData* data,
                                     void (*handler)(int)) {
  data->previous_handler = signal(data->signo, handler);
  ABSL_RAW_CHECK(data->previous_handler != SIG_ERR, "signal() failed");
}

#endif

static void WriteToStderr(const char* data) {
  absl::raw_log_internal::AsyncSignalSafeWriteToStderr(data, strlen(data));
}

static void WriteSignalMessage(int signo, int cpu,
                               void (*writerfn)(const char*)) {
  char buf[96];
  char on_cpu[32] = {0};
  if (cpu != -1) {
    snprintf(on_cpu, sizeof(on_cpu), " on cpu %d", cpu);
  }
  const char* const signal_string =
      debugging_internal::FailureSignalToString(signo);
  if (signal_string != nullptr && signal_string[0] != '\0') {
    snprintf(buf, sizeof(buf), "*** %s received at time=%ld%s ***\n",
             signal_string,
             static_cast<long>(time(nullptr)),   // NOLINT(runtime/int)
             on_cpu);
  } else {
    snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld%s ***\n",
             signo, static_cast<long>(time(nullptr)),  // NOLINT(runtime/int)
             on_cpu);
  }
  writerfn(buf);
}

// `void*` might not be big enough to store `void(*)(const char*)`.
struct WriterFnStruct {
  void (*writerfn)(const char*);
};

// Many of the absl::debugging_internal::Dump* functions in
// examine_stack.h take a writer function pointer that has a void* arg
// for historical reasons. failure_signal_handler_writer only takes a
// data pointer. This function converts between these types.
static void WriterFnWrapper(const char* data, void* arg) {
  static_cast<WriterFnStruct*>(arg)->writerfn(data);
}

// Convenient wrapper around DumpPCAndFrameSizesAndStackTrace() for signal
// handlers. "noinline" so that GetStackFrames() skips the top-most stack
// frame for this function.
ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace(
    void* ucontext, bool symbolize_stacktrace,
    void (*writerfn)(const char*, void*), void* writerfn_arg) {
  constexpr int kNumStackFrames = 32;
  void* stack[kNumStackFrames];
  int frame_sizes[kNumStackFrames];
  int min_dropped_frames;
  int depth = absl::GetStackFramesWithContext(
      stack, frame_sizes, kNumStackFrames,
      1,  // Do not include this function in stack trace.
      ucontext, &min_dropped_frames);
  absl::debugging_internal::DumpPCAndFrameSizesAndStackTrace(
      absl::debugging_internal::GetProgramCounter(ucontext), stack, frame_sizes,
      depth, min_dropped_frames, symbolize_stacktrace, writerfn, writerfn_arg);
}

// Called by AbslFailureSignalHandler() to write the failure info. It is
// called once with writerfn set to WriteToStderr() and then possibly
// with writerfn set to the user provided function.
static void WriteFailureInfo(int signo, void* ucontext, int cpu,
                             void (*writerfn)(const char*)) {
  WriterFnStruct writerfn_struct{writerfn};
  WriteSignalMessage(signo, cpu, writerfn);
  WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper,
                  &writerfn_struct);
}

// absl::SleepFor() can't be used here since AbslInternalSleepFor()
// may be overridden to do something that isn't async-signal-safe on
// some platforms.
static void PortableSleepForSeconds(int seconds) {
#ifdef _WIN32
  Sleep(static_cast<DWORD>(seconds * 1000));
#else
  struct timespec sleep_time;
  sleep_time.tv_sec = seconds;
  sleep_time.tv_nsec = 0;
  while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {}
#endif
}

#ifdef ABSL_HAVE_ALARM
// AbslFailureSignalHandler() installs this as a signal handler for
// SIGALRM, then sets an alarm to be delivered to the program after a
// set amount of time. If AbslFailureSignalHandler() hangs for more than
// the alarm timeout, ImmediateAbortSignalHandler() will abort the
// program.
static void ImmediateAbortSignalHandler(int) {
  RaiseToDefaultHandler(SIGABRT);
}
#endif

// absl::base_internal::GetTID() returns pid_t on most platforms, but
// returns absl::base_internal::pid_t on Windows.
using GetTidType = decltype(absl::base_internal::GetTID());
ABSL_CONST_INIT static std::atomic<GetTidType> failed_tid(0);

#ifndef ABSL_HAVE_SIGACTION
static void AbslFailureSignalHandler(int signo) {
  void* ucontext = nullptr;
#else
static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
#endif

  const GetTidType this_tid = absl::base_internal::GetTID();
  GetTidType previous_failed_tid = 0;
  if (!failed_tid.compare_exchange_strong(previous_failed_tid, this_tid,
                                          std::memory_order_acq_rel,
                                          std::memory_order_relaxed)) {
    ABSL_RAW_LOG(
        ERROR,
        "Signal %d raised at PC=%p while already in AbslFailureSignalHandler()",
        signo, absl::debugging_internal::GetProgramCounter(ucontext));
    if (this_tid != previous_failed_tid) {
      // Another thread is already in AbslFailureSignalHandler(), so wait
      // a bit for it to finish. If the other thread doesn't kill us,
      // we do so after sleeping.
      PortableSleepForSeconds(3);
      RaiseToDefaultHandler(signo);
      // The recursively raised signal may be blocked until we return.
      return;
    }
  }

  // Increase the chance that the CPU we report was the same CPU on which the
  // signal was received by doing this as early as possible, i.e. after
  // verifying that this is not a recursive signal handler invocation.
  int my_cpu = -1;
#ifdef ABSL_HAVE_SCHED_GETCPU
  my_cpu = sched_getcpu();
#endif

#ifdef ABSL_HAVE_ALARM
  // Set an alarm to abort the program in case this code hangs or deadlocks.
  if (fsh_options.alarm_on_failure_secs > 0) {
    alarm(0);  // Cancel any existing alarms.
    signal(SIGALRM, ImmediateAbortSignalHandler);
    alarm(static_cast<unsigned int>(fsh_options.alarm_on_failure_secs));
  }
#endif

  // First write to stderr.
  WriteFailureInfo(signo, ucontext, my_cpu, WriteToStderr);

  // Riskier code (because it is less likely to be async-signal-safe)
  // goes after this point.
  if (fsh_options.writerfn != nullptr) {
    WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn);
    fsh_options.writerfn(nullptr);
  }

  if (fsh_options.call_previous_handler) {
    RaiseToPreviousHandler(signo);
  } else {
    RaiseToDefaultHandler(signo);
  }
}

void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) {
  fsh_options = options;
  for (auto& it : failure_signal_data) {
    InstallOneFailureHandler(&it, AbslFailureSignalHandler);
  }
}

ABSL_NAMESPACE_END
}  // namespace absl
