/*
 * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "code/compiledMethod.hpp"
#include "code/nativeInst.hpp"
#include "jvm.h"
#include "logging/log.hpp"
#include "os_posix.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/os.hpp"
#include "runtime/osThread.hpp"
#include "runtime/safefetch.hpp"
#include "runtime/semaphore.inline.hpp"
#include "runtime/suspendedThreadTask.hpp"
#include "runtime/threadCrashProtection.hpp"
#include "signals_posix.hpp"
#include "suspendResume_posix.hpp"
#include "utilities/events.hpp"
#include "utilities/ostream.hpp"
#include "utilities/vmError.hpp"

#include <signal.h>


static const char* get_signal_name(int sig, char* out, size_t outlen);

// Returns address of a handler associated with the given sigaction
static address get_signal_handler(const struct sigaction* action);

#define HANDLER_IS(handler, address)    ((handler) == CAST_FROM_FN_PTR(void*, (address)))
#define HANDLER_IS_IGN(handler)         (HANDLER_IS(handler, SIG_IGN))
#define HANDLER_IS_DFL(handler)         (HANDLER_IS(handler, SIG_DFL))
#define HANDLER_IS_IGN_OR_DFL(handler)  (HANDLER_IS_IGN(handler) || HANDLER_IS_DFL(handler))

// Various signal related mechanism are laid out in the following order:
//
// sun.misc.Signal
// signal chaining
// signal handling (except suspend/resume)
// suspend/resume

// Helper function to strip any flags from a sigaction sa_flag
// which are not needed for semantic comparison (see remarks below
// about SA_RESTORER on Linux).
// Also to work around the fact that not all platforms define sa_flags
// as signed int (looking at you, zlinux).
static int get_sanitized_sa_flags(const struct sigaction* sa) {
  int f = (int) sa->sa_flags;
#ifdef LINUX
  // Glibc on Linux uses the SA_RESTORER flag to indicate
  // the use of a "signal trampoline". We have no interest
  // in this flag and need to ignore it when checking our
  // own flag settings.
  // Note: SA_RESTORER is not exposed through signal.h so we
  // have to hardcode its 0x04000000 value here.
  const int sa_restorer_flag = 0x04000000;
  f &= ~sa_restorer_flag;
#endif // LINUX
  return f;
}

// Todo: provide a os::get_max_process_id() or similar. Number of processes
// may have been configured, can be read more accurately from proc fs etc.
#ifndef MAX_PID
  #define MAX_PID INT_MAX
#endif
#define IS_VALID_PID(p) (p > 0 && p < MAX_PID)

#define NUM_IMPORTANT_SIGS 32

// At various places we store handler information for each installed handler.
//  SavedSignalHandlers is a helper class for those cases, keeping an array of sigaction
//  structures.
class SavedSignalHandlers {
  // Note: NSIG can be largish, depending on platform, and this array is expected
  // to be sparsely populated. To save space the contained structures are
  // C-heap allocated. Since they only get added outside of signal handling
  // this is no problem.
  struct sigaction* _sa[NSIG];

  bool check_signal_number(int sig) const {
    assert(sig > 0 && sig < NSIG, "invalid signal number %d", sig);
    return sig > 0 && sig < NSIG;
  }

public:

  SavedSignalHandlers() {
    ::memset(_sa, 0, sizeof(_sa));
  }

  ~SavedSignalHandlers() {
    for (int i = 0; i < NSIG; i ++) {
      FREE_C_HEAP_OBJ(_sa[i]);
    }
  }

  void set(int sig, const struct sigaction* act) {
    if (check_signal_number(sig)) {
      assert(_sa[sig] == nullptr, "Overwriting signal handler?");
      _sa[sig] = NEW_C_HEAP_OBJ(struct sigaction, mtInternal);
      *_sa[sig] = *act;
    }
  }

  const struct sigaction* get(int sig) const {
    if (check_signal_number(sig)) {
      return _sa[sig];
    }
    return nullptr;
  }
};


debug_only(static bool signal_sets_initialized = false);
static sigset_t unblocked_sigs, vm_sigs, preinstalled_sigs;

// Our own signal handlers should never ever get replaced by a third party one.
//  To check that, and to aid with diagnostics, store a copy of the handler setup
//  and compare it periodically against reality (see os::run_periodic_checks()).
static bool check_signals = true;
static SavedSignalHandlers vm_handlers;
static bool do_check_signal_periodically[NSIG] = { 0 };

// For signal-chaining:
//  if chaining is active, chained_handlers contains all handlers which we
//  replaced with our own and to which we must delegate.
static SavedSignalHandlers chained_handlers;
static bool libjsig_is_loaded = false;
typedef struct sigaction *(*get_signal_t)(int);
static get_signal_t get_signal_action = nullptr;

// suspend/resume support
#if defined(__APPLE__)
  static OSXSemaphore sr_semaphore;
#else
  static PosixSemaphore sr_semaphore;
#endif

// Signal number used to suspend/resume a thread
// do not use any signal number less than SIGSEGV, see 4355769
int PosixSignals::SR_signum = SIGUSR2;

// sun.misc.Signal support
static Semaphore* sig_semaphore = nullptr;
// a counter for each possible signal value
static volatile jint pending_signals[NSIG+1] = { 0 };

static const struct {
  int sig; const char* name;
} g_signal_info[] = {
  {  SIGABRT,     "SIGABRT" },
#ifdef SIGAIO
  {  SIGAIO,      "SIGAIO" },
#endif
  {  SIGALRM,     "SIGALRM" },
#ifdef SIGALRM1
  {  SIGALRM1,    "SIGALRM1" },
#endif
  {  SIGBUS,      "SIGBUS" },
#ifdef SIGCANCEL
  {  SIGCANCEL,   "SIGCANCEL" },
#endif
  {  SIGCHLD,     "SIGCHLD" },
#ifdef SIGCLD
  {  SIGCLD,      "SIGCLD" },
#endif
  {  SIGCONT,     "SIGCONT" },
#ifdef SIGCPUFAIL
  {  SIGCPUFAIL,  "SIGCPUFAIL" },
#endif
#ifdef SIGDANGER
  {  SIGDANGER,   "SIGDANGER" },
#endif
#ifdef SIGDIL
  {  SIGDIL,      "SIGDIL" },
#endif
#ifdef SIGEMT
  {  SIGEMT,      "SIGEMT" },
#endif
  {  SIGFPE,      "SIGFPE" },
#ifdef SIGFREEZE
  {  SIGFREEZE,   "SIGFREEZE" },
#endif
#ifdef SIGGFAULT
  {  SIGGFAULT,   "SIGGFAULT" },
#endif
#ifdef SIGGRANT
  {  SIGGRANT,    "SIGGRANT" },
#endif
  {  SIGHUP,      "SIGHUP" },
  {  SIGILL,      "SIGILL" },
#ifdef SIGINFO
  {  SIGINFO,     "SIGINFO" },
#endif
  {  SIGINT,      "SIGINT" },
#ifdef SIGIO
  {  SIGIO,       "SIGIO" },
#endif
#ifdef SIGIOINT
  {  SIGIOINT,    "SIGIOINT" },
#endif
#ifdef SIGIOT
// SIGIOT is there for BSD compatibility, but on most Unices just a
// synonym for SIGABRT. The result should be "SIGABRT", not
// "SIGIOT".
#if (SIGIOT != SIGABRT )
  {  SIGIOT,      "SIGIOT" },
#endif
#endif
#ifdef SIGKAP
  {  SIGKAP,      "SIGKAP" },
#endif
  {  SIGKILL,     "SIGKILL" },
#ifdef SIGLOST
  {  SIGLOST,     "SIGLOST" },
#endif
#ifdef SIGLWP
  {  SIGLWP,      "SIGLWP" },
#endif
#ifdef SIGLWPTIMER
  {  SIGLWPTIMER, "SIGLWPTIMER" },
#endif
#ifdef SIGMIGRATE
  {  SIGMIGRATE,  "SIGMIGRATE" },
#endif
#ifdef SIGMSG
  {  SIGMSG,      "SIGMSG" },
#endif
  {  SIGPIPE,     "SIGPIPE" },
#ifdef SIGPOLL
  {  SIGPOLL,     "SIGPOLL" },
#endif
#ifdef SIGPRE
  {  SIGPRE,      "SIGPRE" },
#endif
  {  SIGPROF,     "SIGPROF" },
#ifdef SIGPTY
  {  SIGPTY,      "SIGPTY" },
#endif
#ifdef SIGPWR
  {  SIGPWR,      "SIGPWR" },
#endif
  {  SIGQUIT,     "SIGQUIT" },
#ifdef SIGRECONFIG
  {  SIGRECONFIG, "SIGRECONFIG" },
#endif
#ifdef SIGRECOVERY
  {  SIGRECOVERY, "SIGRECOVERY" },
#endif
#ifdef SIGRESERVE
  {  SIGRESERVE,  "SIGRESERVE" },
#endif
#ifdef SIGRETRACT
  {  SIGRETRACT,  "SIGRETRACT" },
#endif
#ifdef SIGSAK
  {  SIGSAK,      "SIGSAK" },
#endif
  {  SIGSEGV,     "SIGSEGV" },
#ifdef SIGSOUND
  {  SIGSOUND,    "SIGSOUND" },
#endif
#ifdef SIGSTKFLT
  {  SIGSTKFLT,    "SIGSTKFLT" },
#endif
  {  SIGSTOP,     "SIGSTOP" },
  {  SIGSYS,      "SIGSYS" },
#ifdef SIGSYSERROR
  {  SIGSYSERROR, "SIGSYSERROR" },
#endif
#ifdef SIGTALRM
  {  SIGTALRM,    "SIGTALRM" },
#endif
  {  SIGTERM,     "SIGTERM" },
#ifdef SIGTHAW
  {  SIGTHAW,     "SIGTHAW" },
#endif
  {  SIGTRAP,     "SIGTRAP" },
#ifdef SIGTSTP
  {  SIGTSTP,     "SIGTSTP" },
#endif
  {  SIGTTIN,     "SIGTTIN" },
  {  SIGTTOU,     "SIGTTOU" },
#ifdef SIGURG
  {  SIGURG,      "SIGURG" },
#endif
  {  SIGUSR1,     "SIGUSR1" },
  {  SIGUSR2,     "SIGUSR2" },
#ifdef SIGVIRT
  {  SIGVIRT,     "SIGVIRT" },
#endif
  {  SIGVTALRM,   "SIGVTALRM" },
#ifdef SIGWAITING
  {  SIGWAITING,  "SIGWAITING" },
#endif
#ifdef SIGWINCH
  {  SIGWINCH,    "SIGWINCH" },
#endif
#ifdef SIGWINDOW
  {  SIGWINDOW,   "SIGWINDOW" },
#endif
  {  SIGXCPU,     "SIGXCPU" },
  {  SIGXFSZ,     "SIGXFSZ" },
#ifdef SIGXRES
  {  SIGXRES,     "SIGXRES" },
#endif
  { -1, nullptr }
};

////////////////////////////////////////////////////////////////////////////////
// sun.misc.Signal and BREAK_SIGNAL support

void jdk_misc_signal_init() {
  // Initialize signal structures
  ::memset((void*)pending_signals, 0, sizeof(pending_signals));

  // Initialize signal semaphore
  sig_semaphore = new Semaphore();
}

void os::signal_notify(int sig) {
  if (sig_semaphore != nullptr) {
    Atomic::inc(&pending_signals[sig]);
    sig_semaphore->signal();
  } else {
    // Signal thread is not created with ReduceSignalUsage and jdk_misc_signal_init
    // initialization isn't called.
    assert(ReduceSignalUsage, "signal semaphore should be created");
  }
}

static int check_pending_signals() {
  for (;;) {
    for (int i = 0; i < NSIG + 1; i++) {
      jint n = pending_signals[i];
      if (n > 0 && n == Atomic::cmpxchg(&pending_signals[i], n, n - 1)) {
        return i;
      }
    }
    sig_semaphore->wait_with_safepoint_check(JavaThread::current());
  }
  ShouldNotReachHere();
  return 0; // Satisfy compiler
}

int os::signal_wait() {
  return check_pending_signals();
}

////////////////////////////////////////////////////////////////////////////////
// signal chaining support

struct sigaction* get_chained_signal_action(int sig) {
  struct sigaction *actp = nullptr;

  if (libjsig_is_loaded) {
    // Retrieve the old signal handler from libjsig
    actp = (*get_signal_action)(sig);
  }
  if (actp == nullptr) {
    // Retrieve the preinstalled signal handler from jvm
    actp = const_cast<struct sigaction*>(chained_handlers.get(sig));
  }

  return actp;
}

static bool call_chained_handler(struct sigaction *actp, int sig,
                                 siginfo_t *siginfo, void *context) {
  // Call the old signal handler
  if (actp->sa_handler == SIG_DFL) {
    // It's more reasonable to let jvm treat it as an unexpected exception
    // instead of taking the default action.
    return false;
  } else if (actp->sa_handler != SIG_IGN) {
    if ((actp->sa_flags & SA_NODEFER) == 0) {
      // automatically block the signal
      sigaddset(&(actp->sa_mask), sig);
    }

    sa_handler_t hand = nullptr;
    sa_sigaction_t sa = nullptr;
    bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
    // retrieve the chained handler
    if (siginfo_flag_set) {
      sa = actp->sa_sigaction;
    } else {
      hand = actp->sa_handler;
    }

    if ((actp->sa_flags & SA_RESETHAND) != 0) {
      actp->sa_handler = SIG_DFL;
    }

    // try to honor the signal mask
    sigset_t oset;
    sigemptyset(&oset);
    pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);

    // call into the chained handler
    if (siginfo_flag_set) {
      (*sa)(sig, siginfo, context);
    } else {
      (*hand)(sig);
    }

    // restore the signal mask
    pthread_sigmask(SIG_SETMASK, &oset, nullptr);
  }
  // Tell jvm's signal handler the signal is taken care of.
  return true;
}

bool PosixSignals::chained_handler(int sig, siginfo_t* siginfo, void* context) {
  bool chained = false;
  // signal-chaining
  if (UseSignalChaining) {
    struct sigaction *actp = get_chained_signal_action(sig);
    if (actp != nullptr) {
      chained = call_chained_handler(actp, sig, siginfo, context);
    }
  }
  return chained;
}

///// Synchronous (non-deferrable) error signals (ILL, SEGV, FPE, BUS, TRAP):

// These signals are special because they cannot be deferred and, if they
// happen while delivery is blocked for the receiving thread, will cause UB
// (in practice typically resulting in sudden process deaths or hangs, see
// JDK-8252533). So we must take care never to block them when we cannot be
// absolutely sure they won't happen. In practice, this is always.
//
// Relevant Posix quote:
// "The behavior of a process is undefined after it ignores a SIGFPE, SIGILL,
//  SIGSEGV, or SIGBUS signal that was not generated by kill(), sigqueue(), or
//  raise()."
//
// We also include SIGTRAP in that list of never-to-block-signals. While not
// mentioned by the Posix documentation, in our (SAPs) experience blocking it
// causes similar problems. Beside, during normal operation - outside of error
// handling - SIGTRAP may be used for implicit null checking, so it makes sense
// to never block it.
//
// We deal with those signals in two ways:
// - we just never explicitly block them, which includes not accidentally blocking
//   them via sa_mask when establishing signal handlers.
// - as an additional safety measure, at the entrance of a signal handler, we
//   unblock them explicitly.

static void add_error_signals_to_set(sigset_t* set) {
  sigaddset(set, SIGILL);
  sigaddset(set, SIGBUS);
  sigaddset(set, SIGFPE);
  sigaddset(set, SIGSEGV);
  sigaddset(set, SIGTRAP);
}

static void remove_error_signals_from_set(sigset_t* set) {
  sigdelset(set, SIGILL);
  sigdelset(set, SIGBUS);
  sigdelset(set, SIGFPE);
  sigdelset(set, SIGSEGV);
  sigdelset(set, SIGTRAP);
}

// Unblock all signals whose delivery cannot be deferred and which, if they happen
//  while delivery is blocked, would cause crashes or hangs (JDK-8252533).
void PosixSignals::unblock_error_signals() {
  sigset_t set;
  sigemptyset(&set);
  add_error_signals_to_set(&set);
  ::pthread_sigmask(SIG_UNBLOCK, &set, nullptr);
}

class ErrnoPreserver: public StackObj {
  const int _saved;
public:
  ErrnoPreserver() : _saved(errno) {}
  ~ErrnoPreserver() { errno = _saved; }
};

////////////////////////////////////////////////////////////////////////////////
// JVM_handle_(linux|aix|bsd)_signal()

// This routine is the shared part of the central hotspot signal handler. It can
// also be called by a user application, if a user application prefers to do
// signal handling itself - in that case it needs to pass signals the VM
// internally uses on to the VM first.
//
// The user-defined signal handler must pass unrecognized signals to this
// routine, and if it returns true (non-zero), then the signal handler must
// return immediately.  If the flag "abort_if_unrecognized" is true, then this
// routine will never return false (zero), but instead will execute a VM panic
// routine to kill the process.
//
// If this routine returns false, it is OK to call it again.  This allows
// the user-defined signal handler to perform checks either before or after
// the VM performs its own checks.  Naturally, the user code would be making
// a serious error if it tried to handle an exception (such as a null check
// or breakpoint) that the VM was generating for its own correct operation.
//
// This routine may recognize any of the following kinds of signals:
//    SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
// It should be consulted by handlers for any of those signals.
//
// The caller of this routine must pass in the three arguments supplied
// to the function referred to in the "sa_sigaction" (not the "sa_handler")
// field of the structure passed to sigaction().  This routine assumes that
// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
//
// Note that the VM will print warnings if it detects conflicting signal
// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
//

#if defined(BSD)
#define JVM_HANDLE_XXX_SIGNAL JVM_handle_bsd_signal
#elif defined(AIX)
#define JVM_HANDLE_XXX_SIGNAL JVM_handle_aix_signal
#elif defined(LINUX)
#define JVM_HANDLE_XXX_SIGNAL JVM_handle_linux_signal
#else
#error who are you?
#endif

extern "C" JNIEXPORT
int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info,
                          void* ucVoid, int abort_if_unrecognized)
{
  assert(info != nullptr && ucVoid != nullptr, "sanity");

  // Note: it's not uncommon that JNI code uses signal/sigset to install,
  // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
  // or have a SIGILL handler when detecting CPU type). When that happens,
  // this handler might be invoked with junk info/ucVoid. To avoid unnecessary
  // crash when libjsig is not preloaded, try handle signals that do not require
  // siginfo/ucontext first.

  // Preserve errno value over signal handler.
  //  (note: RAII ok here, even with JFR thread crash protection, see below).
  ErrnoPreserver ep;

  // Unblock all synchronous error signals (see JDK-8252533)
  PosixSignals::unblock_error_signals();

  ucontext_t* const uc = (ucontext_t*) ucVoid;
  Thread* const t = Thread::current_or_null_safe();

  // Handle JFR thread crash protection.
  //  Note: this may cause us to longjmp away. Do not use any code before this
  //  point which really needs any form of epilogue code running, eg RAII objects.
  ThreadCrashProtection::check_crash_protection(sig, t);

  bool signal_was_handled = false;

  // Handle assertion poison page accesses.
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
  if (!signal_was_handled &&
      ((sig == SIGSEGV || sig == SIGBUS) && info != nullptr && info->si_addr == g_assert_poison)) {
    signal_was_handled = handle_assert_poison_fault(ucVoid, info->si_addr);
  }
#endif

  // Extract pc from context. Note that for certain signals and certain
  // architectures the pc in ucontext_t will point *after* the offending
  // instruction. In those cases, use siginfo si_addr instead.
  address pc = nullptr;
  if (uc != nullptr) {
    if (S390_ONLY(sig == SIGILL || sig == SIGFPE) NOT_S390(false)) {
      pc = (address)info->si_addr;
    } else {
      pc = os::Posix::ucontext_get_pc(uc);
    }
  }

  if (!signal_was_handled) {
    signal_was_handled = handle_safefetch(sig, pc, uc);
  }

  // Ignore SIGPIPE and SIGXFSZ (4229104, 6499219).
  if (!signal_was_handled &&
      (sig == SIGPIPE || sig == SIGXFSZ)) {
    PosixSignals::chained_handler(sig, info, ucVoid);
    signal_was_handled = true; // unconditionally.
  }

#ifndef ZERO
  // Check for UD trap caused by NOP patching.
  // If it is, patch return address to be deopt handler.
  if (!signal_was_handled && pc != nullptr && os::is_readable_pointer(pc)) {
    if (NativeDeoptInstruction::is_deopt_at(pc)) {
      CodeBlob* cb = CodeCache::find_blob(pc);
      if (cb != nullptr && cb->is_compiled()) {
        MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, t);) // can call PcDescCache::add_pc_desc
        CompiledMethod* cm = cb->as_compiled_method();
        assert(cm->insts_contains_inclusive(pc), "");
        address deopt = cm->is_method_handle_return(pc) ?
          cm->deopt_mh_handler_begin() :
          cm->deopt_handler_begin();
        assert(deopt != nullptr, "");

        frame fr = os::fetch_frame_from_context(uc);
        cm->set_original_pc(&fr, pc);

        os::Posix::ucontext_set_pc(uc, deopt);
        signal_was_handled = true;
      }
    }
  }
#endif // !ZERO

  // Call platform dependent signal handler.
  if (!signal_was_handled) {
    JavaThread* const jt = (t != nullptr && t->is_Java_thread()) ? JavaThread::cast(t) : nullptr;
    signal_was_handled = PosixSignals::pd_hotspot_signal_handler(sig, info, uc, jt);
  }

  // From here on, if the signal had not been handled, it is a fatal error.

  // Give the chained signal handler - should it exist - a shot.
  if (!signal_was_handled) {
    signal_was_handled = PosixSignals::chained_handler(sig, info, ucVoid);
  }

  // Invoke fatal error handling.
  if (!signal_was_handled && abort_if_unrecognized) {
    VMError::report_and_die(t, sig, pc, info, ucVoid);
    // VMError should not return.
    ShouldNotReachHere();
  }
  return signal_was_handled;
}

// Entry point for the hotspot signal handler.
static void javaSignalHandler(int sig, siginfo_t* info, void* context) {
  // Do not add any code here!
  // Only add code to either JVM_HANDLE_XXX_SIGNAL or PosixSignals::pd_hotspot_signal_handler.
  (void)JVM_HANDLE_XXX_SIGNAL(sig, info, context, true);
}

static void UserHandler(int sig, siginfo_t* siginfo, void* context) {

  PosixSignals::unblock_error_signals();

  // Ctrl-C is pressed during error reporting, likely because the error
  // handler fails to abort. Let VM die immediately.
  if (sig == SIGINT && VMError::is_error_reported()) {
    os::die();
  }

  os::signal_notify(sig);
}

static void print_signal_handler_name(outputStream* os, address handler, char* buf, size_t buflen) {
  // We demangle, but omit arguments - signal handlers should have always the same prototype.
  os::print_function_and_library_name(os, handler, buf, buflen,
                                       true, // shorten_path
                                       true, // demangle
                                       true  // omit arguments
                                       );
}

// Writes one-line description of a combination of sigaction.sa_flags into a user
// provided buffer. Returns that buffer.
static const char* describe_sa_flags(int flags, char* buffer, size_t size) {
  char* p = buffer;
  size_t remaining = size;
  bool first = true;
  int idx = 0;

  assert(buffer, "invalid argument");

  if (size == 0) {
    return buffer;
  }

  strncpy(buffer, "none", size);

  const unsigned int unknown_flag = ~(SA_NOCLDSTOP |
                                      SA_ONSTACK   |
                                      SA_NOCLDSTOP |
                                      SA_RESTART   |
                                      SA_SIGINFO   |
                                      SA_NOCLDWAIT |
                                      SA_NODEFER
                                      AIX_ONLY(| SA_OLDSTYLE)
                                      );

  const struct {
    // NB: i is an unsigned int here because SA_RESETHAND is on some
    // systems 0x80000000, which is implicitly unsigned.  Assigning
    // it to an int field would be an overflow in unsigned-to-signed
    // conversion.
    unsigned int i;
    const char* s;
  } flaginfo [] = {
    { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
    { SA_ONSTACK,   "SA_ONSTACK"   },
    { SA_RESETHAND, "SA_RESETHAND" },
    { SA_RESTART,   "SA_RESTART"   },
    { SA_SIGINFO,   "SA_SIGINFO"   },
    { SA_NOCLDWAIT, "SA_NOCLDWAIT" },
    { SA_NODEFER,   "SA_NODEFER"   },
#if defined(AIX)
    { SA_OLDSTYLE,  "SA_OLDSTYLE"  },
#endif
    { unknown_flag, "NOT USED"     }
  };

  for (idx = 0; flaginfo[idx].i != unknown_flag && remaining > 1; idx++) {
    if (flags & flaginfo[idx].i) {
      if (first) {
        jio_snprintf(p, remaining, "%s", flaginfo[idx].s);
        first = false;
      } else {
        jio_snprintf(p, remaining, "|%s", flaginfo[idx].s);
      }
      const size_t len = strlen(p);
      p += len;
      remaining -= len;
    }
  }
  unsigned int unknowns = flags & unknown_flag;
  if (unknowns != 0) {
    jio_snprintf(p, remaining, "|Unknown_flags:%x", unknowns);
  }

  buffer[size - 1] = '\0';

  return buffer;
}

// Prints one-line description of a combination of sigaction.sa_flags.
static void print_sa_flags(outputStream* st, int flags) {
  char buffer[0x100];
  describe_sa_flags(flags, buffer, sizeof(buffer));
  st->print("%s", buffer);
}

// Implementation may use the same storage for both the sa_sigaction field and the sa_handler field,
// so check for "sigAct.sa_flags == SA_SIGINFO"
static address get_signal_handler(const struct sigaction* action) {
  bool siginfo_flag_set = (action->sa_flags & SA_SIGINFO) != 0;
  if (siginfo_flag_set) {
    return CAST_FROM_FN_PTR(address, action->sa_sigaction);
  } else {
    return CAST_FROM_FN_PTR(address, action->sa_handler);
  }
}

typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);

static void SR_handler(int sig, siginfo_t* siginfo, void* context);

// Semantically compare two sigaction structures. Return true if they are referring to
// the same handler, using the same flags.
static bool are_actions_equal(const struct sigaction* sa,
                              const struct sigaction* expected_sa) {
  address this_handler = get_signal_handler(sa);
  address expected_handler = get_signal_handler(expected_sa);
  const int this_flags = get_sanitized_sa_flags(sa);
  const int expected_flags = get_sanitized_sa_flags(expected_sa);
  return (this_handler == expected_handler) &&
         (this_flags == expected_flags);
}

// If we installed one of our signal handlers for sig, check that the current
// setup matches what we originally installed.  Return true if signal handler
// is different.  Otherwise, return false;
static bool check_signal_handler(int sig) {
  char buf[O_BUFLEN];
  bool mismatch = false;

  if (!do_check_signal_periodically[sig]) {
    return false;
  }

  const struct sigaction* expected_act = vm_handlers.get(sig);
  assert(expected_act != nullptr, "Sanity");

  // Retrieve current signal setup.
  struct sigaction act;
  static os_sigaction_t os_sigaction = nullptr;
  if (os_sigaction == nullptr) {
    // only trust the default sigaction, in case it has been interposed
    os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
    if (os_sigaction == nullptr) return false;
  }

  os_sigaction(sig, (struct sigaction*)nullptr, &act);

  // Compare both sigaction structures (intelligently; only the members we care about).
  // Ignore if the handler is our own crash handler.
  if (!are_actions_equal(&act, expected_act) &&
      !(HANDLER_IS(get_signal_handler(&act), VMError::crash_handler_address))) {
    tty->print_cr("Warning: %s handler modified!", os::exception_name(sig, buf, sizeof(buf)));
    // If we had a mismatch:
    // - Disable any further checks for this signal - we do not want to flood stdout. Though
    //   depending on which signal had been overwritten, we may die very soon anyway.
    do_check_signal_periodically[sig] = false;
    // Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN
    if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {
      tty->print_cr("Note: Running in non-interactive shell, %s handler is replaced by shell",
                    os::exception_name(sig, buf, O_BUFLEN));
    }
    return true;
  }
  return false;
}

void* PosixSignals::user_handler() {
  return CAST_FROM_FN_PTR(void*, UserHandler);
}

// Used by JVM_RegisterSignal to install a signal handler.
// The allowed set of signals is restricted by the caller.
// The incoming handler is one of:
// - psuedo-handler: SIG_IGN or SIG_DFL
// - the VM's UserHandler of type sa_sigaction_t
// - unknown signal handling function which we assume is also
//   of type sa_sigaction_t - this is a bug - see JDK-8295702
// Returns the currently installed handler.
void* PosixSignals::install_generic_signal_handler(int sig, void* handler) {
  struct sigaction sigAct, oldSigAct;

  sigfillset(&(sigAct.sa_mask));
  remove_error_signals_from_set(&(sigAct.sa_mask));

  sigAct.sa_flags = SA_RESTART;
  if (HANDLER_IS_IGN_OR_DFL(handler)) {
    sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
  } else {
    sigAct.sa_flags |= SA_SIGINFO;
    sigAct.sa_sigaction = CAST_TO_FN_PTR(sa_sigaction_t, handler);
  }

  if (sigaction(sig, &sigAct, &oldSigAct)) {
    // -1 means registration failed
    return (void *)-1;
  }

  return get_signal_handler(&oldSigAct);
}

// Installs the given sigaction handler for the given signal.
// - sigAct: the new struct sigaction to be filled in and used
//           for this signal. The caller must provide this as it
//           may need to be stored/accessed by that caller.
// - oldSigAct: the old struct sigaction that was associated with
//              this signal
// Returns 0 on success and -1 on error.
int PosixSignals::install_sigaction_signal_handler(struct sigaction* sigAct,
                                                   struct sigaction* oldSigAct,
                                                   int sig,
                                                   sa_sigaction_t handler) {
  sigfillset(&sigAct->sa_mask);
  remove_error_signals_from_set(&sigAct->sa_mask);
  sigAct->sa_sigaction = handler;
  sigAct->sa_flags = SA_SIGINFO|SA_RESTART;
#if defined(__APPLE__)
  // Needed for main thread as XNU (Mac OS X kernel) will only deliver SIGSEGV
  // (which starts as SIGBUS) on main thread with faulting address inside "stack+guard pages"
  // if the signal handler declares it will handle it on alternate stack.
  // Notice we only declare we will handle it on alt stack, but we are not
  // actually going to use real alt stack - this is just a workaround.
  // Please see ux_exception.c, method catch_mach_exception_raise for details
  // link http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/uxkern/ux_exception.c
  if (sig == SIGSEGV) {
    sigAct->sa_flags |= SA_ONSTACK;
  }
#endif
  return sigaction(sig, sigAct, oldSigAct);
}

// Will be modified when max signal is changed to be dynamic
int os::sigexitnum_pd() {
  return NSIG;
}

// This method is a periodic task to check for misbehaving JNI applications
// under CheckJNI, we can add any periodic checks here
void os::run_periodic_checks(outputStream* st) {

  if (check_signals == false) return;

  // SEGV and BUS if overridden could potentially prevent
  // generation of hs*.log in the event of a crash, debugging
  // such a case can be very challenging, so we absolutely
  // check the following for a good measure:
  bool print_handlers = false;

  print_handlers |= check_signal_handler(SIGSEGV);
  print_handlers |= check_signal_handler(SIGILL);
  print_handlers |= check_signal_handler(SIGFPE);
  print_handlers |= check_signal_handler(SIGBUS);
  PPC64_ONLY(print_handlers |= check_signal_handler(SIGTRAP);)

  // ReduceSignalUsage allows the user to override these handlers
  // see comments at the very top and jvm_md.h
  if (!ReduceSignalUsage) {
    print_handlers |= check_signal_handler(SHUTDOWN1_SIGNAL);
    print_handlers |= check_signal_handler(SHUTDOWN2_SIGNAL);
    print_handlers |= check_signal_handler(SHUTDOWN3_SIGNAL);
    print_handlers |= check_signal_handler(BREAK_SIGNAL);
  }

  print_handlers |= check_signal_handler(PosixSignals::SR_signum);

  // As we ignore SIGPIPE and SIGXFSZ, and expect other code to potentially
  // install handlers for them, we don't bother checking them here.

  if (print_handlers) {
    // If we had a mismatch:
    // - print all signal handlers. As part of that printout, details will be printed
    //   about any modified handlers.
    char buf[O_BUFLEN];
    os::print_signal_handlers(st, buf, O_BUFLEN);
    st->print_cr("Consider using jsig library.");
  }
}

// Helper function for PosixSignals::print_siginfo_...():
// return a textual description for signal code.
struct enum_sigcode_desc_t {
  const char* s_name;
  const char* s_desc;
};

static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) {

  const struct {
    int sig; int code; const char* s_code; const char* s_desc;
  } t1 [] = {
    { SIGILL,  ILL_ILLOPC,   "ILL_ILLOPC",   "Illegal opcode." },
    { SIGILL,  ILL_ILLOPN,   "ILL_ILLOPN",   "Illegal operand." },
    { SIGILL,  ILL_ILLADR,   "ILL_ILLADR",   "Illegal addressing mode." },
    { SIGILL,  ILL_ILLTRP,   "ILL_ILLTRP",   "Illegal trap." },
    { SIGILL,  ILL_PRVOPC,   "ILL_PRVOPC",   "Privileged opcode." },
    { SIGILL,  ILL_PRVREG,   "ILL_PRVREG",   "Privileged register." },
    { SIGILL,  ILL_COPROC,   "ILL_COPROC",   "Coprocessor error." },
    { SIGILL,  ILL_BADSTK,   "ILL_BADSTK",   "Internal stack error." },
#if defined(IA64) && defined(LINUX)
    { SIGILL,  ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" },
    { SIGILL,  ILL_BREAK,    "ILL_BREAK",    "Application Break instruction" },
#endif
    { SIGFPE,  FPE_INTDIV,   "FPE_INTDIV",   "Integer divide by zero." },
    { SIGFPE,  FPE_INTOVF,   "FPE_INTOVF",   "Integer overflow." },
    { SIGFPE,  FPE_FLTDIV,   "FPE_FLTDIV",   "Floating-point divide by zero." },
    { SIGFPE,  FPE_FLTOVF,   "FPE_FLTOVF",   "Floating-point overflow." },
    { SIGFPE,  FPE_FLTUND,   "FPE_FLTUND",   "Floating-point underflow." },
    { SIGFPE,  FPE_FLTRES,   "FPE_FLTRES",   "Floating-point inexact result." },
    { SIGFPE,  FPE_FLTINV,   "FPE_FLTINV",   "Invalid floating-point operation." },
    { SIGFPE,  FPE_FLTSUB,   "FPE_FLTSUB",   "Subscript out of range." },
    { SIGSEGV, SEGV_MAPERR,  "SEGV_MAPERR",  "Address not mapped to object." },
    { SIGSEGV, SEGV_ACCERR,  "SEGV_ACCERR",  "Invalid permissions for mapped object." },
#if defined(AIX)
    // no explanation found what keyerr would be
    { SIGSEGV, SEGV_KEYERR,  "SEGV_KEYERR",  "key error" },
#endif
#if defined(IA64) && !defined(AIX)
    { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" },
#endif
    { SIGBUS,  BUS_ADRALN,   "BUS_ADRALN",   "Invalid address alignment." },
    { SIGBUS,  BUS_ADRERR,   "BUS_ADRERR",   "Nonexistent physical address." },
    { SIGBUS,  BUS_OBJERR,   "BUS_OBJERR",   "Object-specific hardware error." },
    { SIGTRAP, TRAP_BRKPT,   "TRAP_BRKPT",   "Process breakpoint." },
    { SIGTRAP, TRAP_TRACE,   "TRAP_TRACE",   "Process trace trap." },
    { SIGCHLD, CLD_EXITED,   "CLD_EXITED",   "Child has exited." },
    { SIGCHLD, CLD_KILLED,   "CLD_KILLED",   "Child has terminated abnormally and did not create a core file." },
    { SIGCHLD, CLD_DUMPED,   "CLD_DUMPED",   "Child has terminated abnormally and created a core file." },
    { SIGCHLD, CLD_TRAPPED,  "CLD_TRAPPED",  "Traced child has trapped." },
    { SIGCHLD, CLD_STOPPED,  "CLD_STOPPED",  "Child has stopped." },
    { SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." },
#ifdef SIGPOLL
    { SIGPOLL, POLL_OUT,     "POLL_OUT",     "Output buffers available." },
    { SIGPOLL, POLL_MSG,     "POLL_MSG",     "Input message available." },
    { SIGPOLL, POLL_ERR,     "POLL_ERR",     "I/O error." },
    { SIGPOLL, POLL_PRI,     "POLL_PRI",     "High priority input available." },
    { SIGPOLL, POLL_HUP,     "POLL_HUP",     "Device disconnected. [Option End]" },
#endif
    { -1, -1, nullptr, nullptr }
  };

  // Codes valid in any signal context.
  const struct {
    int code; const char* s_code; const char* s_desc;
  } t2 [] = {
    { SI_USER,      "SI_USER",     "Signal sent by kill()." },
    { SI_QUEUE,     "SI_QUEUE",    "Signal sent by the sigqueue()." },
    { SI_TIMER,     "SI_TIMER",    "Signal generated by expiration of a timer set by timer_settime()." },
    { SI_ASYNCIO,   "SI_ASYNCIO",  "Signal generated by completion of an asynchronous I/O request." },
    { SI_MESGQ,     "SI_MESGQ",    "Signal generated by arrival of a message on an empty message queue." },
    // Linux specific
#ifdef SI_TKILL
    { SI_TKILL,     "SI_TKILL",    "Signal sent by tkill (pthread_kill)" },
#endif
#ifdef SI_DETHREAD
    { SI_DETHREAD,  "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" },
#endif
#ifdef SI_KERNEL
    { SI_KERNEL,    "SI_KERNEL",   "Signal sent by kernel." },
#endif
#ifdef SI_SIGIO
    { SI_SIGIO,     "SI_SIGIO",    "Signal sent by queued SIGIO" },
#endif

#if defined(AIX)
    { SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" },
    { SI_EMPTY,     "SI_EMPTY",    "siginfo contains no useful information" },
#endif

    { -1, nullptr, nullptr }
  };

  const char* s_code = nullptr;
  const char* s_desc = nullptr;

  for (int i = 0; t1[i].sig != -1; i ++) {
    if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) {
      s_code = t1[i].s_code;
      s_desc = t1[i].s_desc;
      break;
    }
  }

  if (s_code == nullptr) {
    for (int i = 0; t2[i].s_code != nullptr; i ++) {
      if (t2[i].code == si->si_code) {
        s_code = t2[i].s_code;
        s_desc = t2[i].s_desc;
      }
    }
  }

  if (s_code == nullptr) {
    out->s_name = "unknown";
    out->s_desc = "unknown";
    return false;
  }

  out->s_name = s_code;
  out->s_desc = s_desc;

  return true;
}

bool os::signal_sent_by_kill(const void* siginfo) {
  const siginfo_t* const si = (const siginfo_t*)siginfo;
  return si->si_code == SI_USER || si->si_code == SI_QUEUE
#ifdef SI_TKILL
         || si->si_code == SI_TKILL
#endif
  ;
}

// Returns true if signal number is valid.
static bool is_valid_signal(int sig) {
  // MacOS not really POSIX compliant: sigaddset does not return
  // an error for invalid signal numbers. However, MacOS does not
  // support real time signals and simply seems to have just 33
  // signals with no holes in the signal range.
#if defined(__APPLE__)
  return sig >= 1 && sig < NSIG;
#else
  // Use sigaddset to check for signal validity.
  sigset_t set;
  sigemptyset(&set);
  if (sigaddset(&set, sig) == -1 && errno == EINVAL) {
    return false;
  }
  return true;
#endif
}

static const char* get_signal_name(int sig, char* out, size_t outlen) {

  const char* ret = nullptr;

#ifdef SIGRTMIN
  if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
    if (sig == SIGRTMIN) {
      ret = "SIGRTMIN";
    } else if (sig == SIGRTMAX) {
      ret = "SIGRTMAX";
    } else {
      jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN);
      return out;
    }
  }
#endif

  if (sig > 0) {
    for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {
      if (g_signal_info[idx].sig == sig) {
        ret = g_signal_info[idx].name;
        break;
      }
    }
  }

  if (!ret) {
    if (!is_valid_signal(sig)) {
      ret = "INVALID";
    } else {
      ret = "UNKNOWN";
    }
  }

  if (out && outlen > 0) {
    strncpy(out, ret, outlen);
    out[outlen - 1] = '\0';
  }
  return out;
}

void os::print_siginfo(outputStream* os, const void* si0) {

  const siginfo_t* const si = (const siginfo_t*) si0;

  char buf[20];
  os->print("siginfo:");

  if (!si) {
    os->print(" <null>");
    return;
  }

  const int sig = si->si_signo;

  os->print(" si_signo: %d (%s)", sig, get_signal_name(sig, buf, sizeof(buf)));

  enum_sigcode_desc_t ed;
  get_signal_code_description(si, &ed);
  os->print(", si_code: %d (%s)", si->si_code, ed.s_name);

  if (si->si_errno) {
    os->print(", si_errno: %d", si->si_errno);
  }

  // Output additional information depending on the signal code.

  // Note: Many implementations lump si_addr, si_pid, si_uid etc. together as unions,
  // so it depends on the context which member to use. For synchronous error signals,
  // we print si_addr, unless the signal was sent by another process or thread, in
  // which case we print out pid or tid of the sender.
  if (os::signal_sent_by_kill(si)) {
    const pid_t pid = si->si_pid;
    os->print(", si_pid: %ld", (long) pid);
    if (IS_VALID_PID(pid)) {
      const pid_t me = getpid();
      if (me == pid) {
        os->print(" (current process)");
      }
    } else {
      os->print(" (invalid)");
    }
    os->print(", si_uid: %ld", (long) si->si_uid);
    if (sig == SIGCHLD) {
      os->print(", si_status: %d", si->si_status);
    }
  } else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
             sig == SIGTRAP || sig == SIGFPE) {
    os->print(", si_addr: " PTR_FORMAT, p2i(si->si_addr));
#ifdef SIGPOLL
  } else if (sig == SIGPOLL) {
    // siginfo_t.si_band is defined as "long", and it is so in most
    // implementations. But SPARC64 glibc has a bug: si_band is "int".
    // Cast si_band to "long" to prevent format specifier mismatch.
    // See: https://sourceware.org/bugzilla/show_bug.cgi?id=23821
    os->print(", si_band: %ld", (long) si->si_band);
#endif
  }
}

bool os::signal_thread(Thread* thread, int sig, const char* reason) {
  OSThread* osthread = thread->osthread();
  if (osthread) {
    int status = pthread_kill(osthread->pthread_id(), sig);
    if (status == 0) {
      Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.",
                  sig, p2i(thread), reason);
      return true;
    }
  }
  return false;
}

// Returns:
// null for an invalid signal number
// "SIG<num>" for a valid but unknown signal number
// signal name otherwise.
const char* os::exception_name(int sig, char* buf, size_t size) {
  if (!is_valid_signal(sig)) {
    return nullptr;
  }
  const char* const name = get_signal_name(sig, buf, size);
  if (strcmp(name, "UNKNOWN") == 0) {
    jio_snprintf(buf, size, "SIG%d", sig);
  }
  return buf;
}

int os::get_signal_number(const char* signal_name) {
  char tmp[30];
  const char* s = signal_name;
  if (s[0] != 'S' || s[1] != 'I' || s[2] != 'G') {
    jio_snprintf(tmp, sizeof(tmp), "SIG%s", signal_name);
    s = tmp;
  }
  for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {
    if (strcmp(g_signal_info[idx].name, s) == 0) {
      return g_signal_info[idx].sig;
    }
  }
  return -1;
}

void set_signal_handler(int sig) {
  // Check for overwrite.
  struct sigaction oldAct;
  sigaction(sig, (struct sigaction*)nullptr, &oldAct);

  // Query the current signal handler. Needs to be a separate operation
  // from installing a new handler since we need to honor AllowUserSignalHandlers.
  void* oldhand = get_signal_handler(&oldAct);
  if (!HANDLER_IS_IGN_OR_DFL(oldhand) &&
      !HANDLER_IS(oldhand, javaSignalHandler)) {
    if (AllowUserSignalHandlers) {
      // Do not overwrite; user takes responsibility to forward to us.
      return;
    } else if (UseSignalChaining) {
      // save the old handler in jvm
      chained_handlers.set(sig, &oldAct);
      // libjsig also interposes the sigaction() call below and saves the
      // old sigaction on it own.
    } else {
      fatal("Encountered unexpected pre-existing sigaction handler "
            "%#lx for signal %d.", (long)oldhand, sig);
    }
  }

  struct sigaction sigAct;
  int ret = PosixSignals::install_sigaction_signal_handler(&sigAct, &oldAct,
                                                           sig, javaSignalHandler);
  assert(ret == 0, "check");

  // Save handler setup for possible later checking
  vm_handlers.set(sig, &sigAct);

  bool do_check = true;
  if (sig == SIGPIPE || sig == SIGXFSZ) {
    // As we ignore these signals, and expect other code to potentially
    // install handlers for them, we don't bother checking them.
    do_check = false;
  }
  do_check_signal_periodically[sig] = do_check;
#ifdef ASSERT
  void* oldhand2  = get_signal_handler(&oldAct);
  assert(oldhand2 == oldhand, "no concurrent signal handler installation");
#endif
}

// install signal handlers for signals that HotSpot needs to
// handle in order to support Java-level exception handling.
void install_signal_handlers() {
  // signal-chaining
  typedef void (*signal_setting_t)();
  signal_setting_t begin_signal_setting = nullptr;
  signal_setting_t end_signal_setting = nullptr;
  begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
                                        dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
  if (begin_signal_setting != nullptr) {
    end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
                                        dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
    get_signal_action = CAST_TO_FN_PTR(get_signal_t,
                                       dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
    libjsig_is_loaded = true;
    assert(UseSignalChaining, "should enable signal-chaining");
  }
  if (libjsig_is_loaded) {
    // Tell libjsig jvm is setting signal handlers
    (*begin_signal_setting)();
  }

  set_signal_handler(SIGSEGV);
  set_signal_handler(SIGPIPE);
  set_signal_handler(SIGBUS);
  set_signal_handler(SIGILL);
  set_signal_handler(SIGFPE);
  PPC64_ONLY(set_signal_handler(SIGTRAP);)
  set_signal_handler(SIGXFSZ);
  if (!ReduceSignalUsage) {
    // Install BREAK_SIGNAL's handler in early initialization phase, in
    // order to reduce the risk that an attach client accidentally forces
    // HotSpot to quit prematurely.
    // The actual work for handling BREAK_SIGNAL is performed by the Signal
    // Dispatcher thread, which is created and started at a much later point,
    // see os::initialize_jdk_signal_support(). Any BREAK_SIGNAL received
    // before the Signal Dispatcher thread is started is queued up via the
    // pending_signals[BREAK_SIGNAL] counter, and will be processed by the
    // Signal Dispatcher thread in a delayed fashion.
    //
    // Also note that HotSpot does NOT support signal chaining for BREAK_SIGNAL.
    // Applications that require a custom BREAK_SIGNAL handler should run with
    // -XX:+ReduceSignalUsage. Otherwise if libjsig is used together with
    // -XX:+ReduceSignalUsage, libjsig will prevent changing BREAK_SIGNAL's
    // handler to a custom handler.
    struct sigaction sigAct, oldSigAct;
    int ret =  PosixSignals::install_sigaction_signal_handler(&sigAct, &oldSigAct,
                                                              BREAK_SIGNAL, UserHandler);
    assert(ret == 0, "check");
  }

#if defined(__APPLE__)
  // lldb (gdb) installs both standard BSD signal handlers, and mach exception
  // handlers. By replacing the existing task exception handler, we disable lldb's mach
  // exception handling, while leaving the standard BSD signal handlers functional.
  //
  // EXC_MASK_BAD_ACCESS needed by all architectures for null ptr checking
  // EXC_MASK_ARITHMETIC needed by all architectures for div by 0 checking
  // EXC_MASK_BAD_INSTRUCTION needed by aarch64 to initiate deoptimization
  kern_return_t kr;
  kr = task_set_exception_ports(mach_task_self(),
                                EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC
                                  AARCH64_ONLY(| EXC_MASK_BAD_INSTRUCTION),
                                MACH_PORT_NULL,
                                EXCEPTION_STATE_IDENTITY,
                                MACHINE_THREAD_STATE);

  assert(kr == KERN_SUCCESS, "could not set mach task signal handler");
#endif

  if (libjsig_is_loaded) {
    // Tell libjsig jvm finishes setting signal handlers
    (*end_signal_setting)();
  }

  // We don't activate signal checker if libjsig is in place, we trust ourselves
  // and if UserSignalHandler is installed all bets are off.
  // Log that signal checking is off only if -verbose:jni is specified.
  if (CheckJNICalls) {
    if (libjsig_is_loaded) {
      log_debug(jni, resolve)("Info: libjsig is activated, all active signal checking is disabled");
      check_signals = false;
    }
    if (AllowUserSignalHandlers) {
      log_debug(jni, resolve)("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
      check_signals = false;
    }
  }
}

// Returns one-line short description of a signal set in a user provided buffer.
static const char* describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) {
  assert(buf_size == (NUM_IMPORTANT_SIGS + 1), "wrong buffer size");
  // Note: for shortness, just print out the first 32. That should
  // cover most of the useful ones, apart from realtime signals.
  for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) {
    const int rc = sigismember(set, sig);
    if (rc == -1 && errno == EINVAL) {
      buffer[sig-1] = '?';
    } else {
      buffer[sig-1] = rc == 0 ? '0' : '1';
    }
  }
  buffer[NUM_IMPORTANT_SIGS] = 0;
  return buffer;
}

// Prints one-line description of a signal set.
static void print_signal_set_short(outputStream* st, const sigset_t* set) {
  char buf[NUM_IMPORTANT_SIGS + 1];
  describe_signal_set_short(set, buf, sizeof(buf));
  st->print("%s", buf);
}

static void print_single_signal_handler(outputStream* st,
                                        const struct sigaction* act,
                                        char* buf, size_t buflen) {

  address handler = get_signal_handler(act);
  if (HANDLER_IS_DFL(handler)) {
    st->print("SIG_DFL");
  } else if (HANDLER_IS_IGN(handler)) {
    st->print("SIG_IGN");
  } else {
    print_signal_handler_name(st, handler, buf, buflen);
  }

  st->print(", mask=");
  print_signal_set_short(st, &(act->sa_mask));

  st->print(", flags=");
  int flags = get_sanitized_sa_flags(act);
  print_sa_flags(st, flags);
}

// Print established signal handler for this signal.
// - if this signal handler was installed by us and is chained to a pre-established user handler
//    it replaced, print that one too.
// - otherwise, if this signal handler was installed by us and replaced another handler to which we
//    are not chained (e.g. if chaining is off), print that one too.
void PosixSignals::print_signal_handler(outputStream* st, int sig,
                                        char* buf, size_t buflen) {

  st->print("%10s: ", os::exception_name(sig, buf, buflen));

  struct sigaction current_act;
  sigaction(sig, nullptr, &current_act);

  print_single_signal_handler(st, &current_act, buf, buflen);

  sigset_t thread_sig_mask;
  if (::pthread_sigmask(/* ignored */ SIG_BLOCK, nullptr, &thread_sig_mask) == 0) {
    st->print(", %s", sigismember(&thread_sig_mask, sig) ? "blocked" : "unblocked");
  }
  st->cr();

  // If we expected to see our own hotspot signal handler but found a different one,
  //  print a warning (unless the handler replacing it is our own crash handler, which can
  //  happen if this function is called during error reporting).
  const struct sigaction* expected_act = vm_handlers.get(sig);
  if (expected_act != nullptr) {
    const address current_handler = get_signal_handler(&current_act);
    if (!(HANDLER_IS(current_handler, VMError::crash_handler_address))) {
      if (!are_actions_equal(&current_act, expected_act)) {
        st->print_cr("  *** Handler was modified!");
        st->print   ("  *** Expected: ");
        print_single_signal_handler(st, expected_act, buf, buflen);
        st->cr();
      }
    }
  }

  // If there is a chained handler waiting behind the current one, print it too.
  const struct sigaction* chained_act = get_chained_signal_action(sig);
  if (chained_act != nullptr) {
    st->print("  chained to: ");
    print_single_signal_handler(st, &current_act, buf, buflen);
    st->cr();
  }
}

void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
  st->print_cr("Signal Handlers:");
  PosixSignals::print_signal_handler(st, SIGSEGV, buf, buflen);
  PosixSignals::print_signal_handler(st, SIGBUS , buf, buflen);
  PosixSignals::print_signal_handler(st, SIGFPE , buf, buflen);
  PosixSignals::print_signal_handler(st, SIGPIPE, buf, buflen);
  PosixSignals::print_signal_handler(st, SIGXFSZ, buf, buflen);
  PosixSignals::print_signal_handler(st, SIGILL , buf, buflen);
  PosixSignals::print_signal_handler(st, PosixSignals::SR_signum, buf, buflen);
  PosixSignals::print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
  PosixSignals::print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
  PosixSignals::print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
  PosixSignals::print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
#if defined(SIGDANGER)
  // We also want to know if someone else adds a SIGDANGER handler because
  // that will interfere with OOM killling.
  PosixSignals::print_signal_handler(st, SIGDANGER, buf, buflen);
#endif
#if defined(SIGTRAP)
  PosixSignals::print_signal_handler(st, SIGTRAP, buf, buflen);
#endif
}

bool PosixSignals::is_sig_ignored(int sig) {
  struct sigaction oact;
  sigaction(sig, (struct sigaction*)nullptr, &oact);
  if (HANDLER_IS_IGN(get_signal_handler(&oact))) {
    return true;
  } else {
    return false;
  }
}

static void signal_sets_init() {
  sigemptyset(&preinstalled_sigs);

  // Should also have an assertion stating we are still single-threaded.
  assert(!signal_sets_initialized, "Already initialized");
  // Fill in signals that are necessarily unblocked for all threads in
  // the VM. Currently, we unblock the following signals:
  // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
  //                         by -Xrs (=ReduceSignalUsage));
  // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
  // other threads. The "ReduceSignalUsage" boolean tells us not to alter
  // the dispositions or masks wrt these signals.
  // Programs embedding the VM that want to use the above signals for their
  // own purposes must, at this time, use the "-Xrs" option to prevent
  // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
  // (See bug 4345157, and other related bugs).
  // In reality, though, unblocking these signals is really a nop, since
  // these signals are not blocked by default.
  sigemptyset(&unblocked_sigs);
  sigaddset(&unblocked_sigs, SIGILL);
  sigaddset(&unblocked_sigs, SIGSEGV);
  sigaddset(&unblocked_sigs, SIGBUS);
  sigaddset(&unblocked_sigs, SIGFPE);
  PPC64_ONLY(sigaddset(&unblocked_sigs, SIGTRAP);)
  sigaddset(&unblocked_sigs, PosixSignals::SR_signum);

  if (!ReduceSignalUsage) {
    if (!PosixSignals::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
      sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
    }
    if (!PosixSignals::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
      sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
    }
    if (!PosixSignals::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
      sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
    }
  }
  // Fill in signals that are blocked by all but the VM thread.
  sigemptyset(&vm_sigs);
  if (!ReduceSignalUsage) {
    sigaddset(&vm_sigs, BREAK_SIGNAL);
  }
  debug_only(signal_sets_initialized = true);
}

// These are signals that are unblocked while a thread is running Java.
// (For some reason, they get blocked by default.)
static sigset_t* unblocked_signals() {
  assert(signal_sets_initialized, "Not initialized");
  return &unblocked_sigs;
}

// These are the signals that are blocked while a (non-VM) thread is
// running Java. Only the VM thread handles these signals.
static sigset_t* vm_signals() {
  assert(signal_sets_initialized, "Not initialized");
  return &vm_sigs;
}

void PosixSignals::hotspot_sigmask(Thread* thread) {

  //Save caller's signal mask before setting VM signal mask
  sigset_t caller_sigmask;
  pthread_sigmask(SIG_BLOCK, nullptr, &caller_sigmask);

  OSThread* osthread = thread->osthread();
  osthread->set_caller_sigmask(caller_sigmask);

  pthread_sigmask(SIG_UNBLOCK, unblocked_signals(), nullptr);

  if (!ReduceSignalUsage) {
    if (thread->is_VM_thread()) {
      // Only the VM thread handles BREAK_SIGNAL ...
      pthread_sigmask(SIG_UNBLOCK, vm_signals(), nullptr);
    } else {
      // ... all other threads block BREAK_SIGNAL
      pthread_sigmask(SIG_BLOCK, vm_signals(), nullptr);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
// suspend/resume support

//  The low-level signal-based suspend/resume support is a remnant from the
//  old VM-suspension that used to be for java-suspension, safepoints etc,
//  within hotspot. Currently used by JFR's OSThreadSampler
//
//  The remaining code is greatly simplified from the more general suspension
//  code that used to be used.
//
//  The protocol is quite simple:
//  - suspend:
//      - sends a signal to the target thread
//      - polls the suspend state of the osthread using a yield loop
//      - target thread signal handler (SR_handler) sets suspend state
//        and blocks in sigsuspend until continued
//  - resume:
//      - sets target osthread state to continue
//      - sends signal to end the sigsuspend loop in the SR_handler
//
//  Note that resume_clear_context() and suspend_save_context() are needed
//  by SR_handler(), so that fetch_frame_from_context() works,
//  which in part is used by:
//    - Forte Analyzer: AsyncGetCallTrace()
//    - StackBanging: get_frame_at_stack_banging_point()

static void resume_clear_context(OSThread *osthread) {
  osthread->set_ucontext(nullptr);
  osthread->set_siginfo(nullptr);
}

static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, void* ucVoid) {
  osthread->set_ucontext((ucontext_t*)ucVoid);
  osthread->set_siginfo(siginfo);
}

// Handler function invoked when a thread's execution is suspended or
// resumed. We have to be careful that only async-safe functions are
// called here (Note: most pthread functions are not async safe and
// should be avoided.)
//
// Note: sigwait() is a more natural fit than sigsuspend() from an
// interface point of view, but sigwait() prevents the signal handler
// from being run. libpthread would get very confused by not having
// its signal handlers run and prevents sigwait()'s use with the
// mutex granting signal.
//
// Currently only ever called on the VMThread and JavaThreads (PC sampling)
//
static void SR_handler(int sig, siginfo_t* siginfo, void* context) {

  // Save and restore errno to avoid confusing native code with EINTR
  // after sigsuspend.
  int old_errno = errno;

  PosixSignals::unblock_error_signals();

  Thread* thread = Thread::current_or_null_safe();

  // The suspend/resume signal may have been sent from outside the process, deliberately or
  // accidentally. In that case the receiving thread may not be attached to the VM. We handle
  // that case by asserting (debug VM) resp. writing a diagnostic message to tty and
  // otherwise ignoring the stray signal (release VMs).
  // We print the siginfo as part of the diagnostics, which also contains the sender pid of
  // the stray signal.
  if (thread == nullptr) {
    stringStream ss;
    ss.print_raw("Non-attached thread received stray SR signal (");
    os::print_siginfo(&ss, siginfo);
    ss.print_raw(").");
    assert(thread != nullptr, "%s.", ss.base());
    log_warning(os)("%s", ss.base());
    return;
  }

  // On some systems we have seen signal delivery get "stuck" until the signal
  // mask is changed as part of thread termination. Check that the current thread
  // has not already terminated - else the following assertion
  // will fail because the thread is no longer a JavaThread as the ~JavaThread
  // destructor has completed.

  if (thread->has_terminated()) {
    return;
  }

  assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");

  OSThread* osthread = thread->osthread();

  SuspendResume::State current = osthread->sr.state();

  if (current == SuspendResume::SR_SUSPEND_REQUEST) {
    suspend_save_context(osthread, siginfo, context);

    // attempt to switch the state, we assume we had a SUSPEND_REQUEST
    SuspendResume::State state = osthread->sr.suspended();
    if (state == SuspendResume::SR_SUSPENDED) {
      sigset_t suspend_set;  // signals for sigsuspend()
      sigemptyset(&suspend_set);

      // get current set of blocked signals and unblock resume signal
      pthread_sigmask(SIG_BLOCK, nullptr, &suspend_set);
      sigdelset(&suspend_set, PosixSignals::SR_signum);

      sr_semaphore.signal();

      // wait here until we are resumed
      while (1) {
        sigsuspend(&suspend_set);

        SuspendResume::State result = osthread->sr.running();
        if (result == SuspendResume::SR_RUNNING) {
          // double check AIX doesn't need this!
          sr_semaphore.signal();
          break;
        } else if (result != SuspendResume::SR_SUSPENDED) {
          ShouldNotReachHere();
        }
      }

    } else if (state == SuspendResume::SR_RUNNING) {
      // request was cancelled, continue
    } else {
      ShouldNotReachHere();
    }

    resume_clear_context(osthread);
  } else if (current == SuspendResume::SR_RUNNING) {
    // request was cancelled, continue
  } else if (current == SuspendResume::SR_WAKEUP_REQUEST) {
    // ignore
  } else {
    // ignore
  }

  errno = old_errno;
}

int SR_initialize() {
  struct sigaction act;
  char *s;
  // Get signal number to use for suspend/resume
  if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
    int sig = ::strtol(s, 0, 10);
    if (sig > MAX2(SIGSEGV, SIGBUS) &&  // See 4355769.
        sig < NSIG) {                   // Must be legal signal and fit into sigflags[].
      PosixSignals::SR_signum = sig;
    } else {
      warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.",
              sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, PosixSignals::SR_signum);
    }
  }

  assert(PosixSignals::SR_signum > SIGSEGV && PosixSignals::SR_signum > SIGBUS,
         "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");

  // Set up signal handler for suspend/resume
  act.sa_flags = SA_RESTART|SA_SIGINFO;
  act.sa_sigaction = SR_handler;

  // SR_signum is blocked when the handler runs.
  pthread_sigmask(SIG_BLOCK, nullptr, &act.sa_mask);
  remove_error_signals_from_set(&(act.sa_mask));

  if (sigaction(PosixSignals::SR_signum, &act, 0) == -1) {
    return -1;
  }

  // Save signal setup information for later checking.
  vm_handlers.set(PosixSignals::SR_signum, &act);
  do_check_signal_periodically[PosixSignals::SR_signum] = true;

  return 0;
}

static int sr_notify(OSThread* osthread) {
  int status = pthread_kill(osthread->pthread_id(), PosixSignals::SR_signum);
  assert_status(status == 0, status, "pthread_kill");
  return status;
}

// returns true on success and false on error - really an error is fatal
// but this seems the normal response to library errors
bool PosixSignals::do_suspend(OSThread* osthread) {
  assert(osthread->sr.is_running(), "thread should be running");
  assert(!sr_semaphore.trywait(), "semaphore has invalid state");

  // mark as suspended and send signal
  if (osthread->sr.request_suspend() != SuspendResume::SR_SUSPEND_REQUEST) {
    // failed to switch, state wasn't running?
    ShouldNotReachHere();
    return false;
  }

  if (sr_notify(osthread) != 0) {
    ShouldNotReachHere();
  }

  // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
  while (true) {
    if (sr_semaphore.timedwait(2)) {
      break;
    } else {
      // timeout
      SuspendResume::State cancelled = osthread->sr.cancel_suspend();
      if (cancelled == SuspendResume::SR_RUNNING) {
        return false;
      } else if (cancelled == SuspendResume::SR_SUSPENDED) {
        // make sure that we consume the signal on the semaphore as well
        sr_semaphore.wait();
        break;
      } else {
        ShouldNotReachHere();
        return false;
      }
    }
  }

  guarantee(osthread->sr.is_suspended(), "Must be suspended");
  return true;
}

void PosixSignals::do_resume(OSThread* osthread) {
  assert(osthread->sr.is_suspended(), "thread should be suspended");
  assert(!sr_semaphore.trywait(), "invalid semaphore state");

  if (osthread->sr.request_wakeup() != SuspendResume::SR_WAKEUP_REQUEST) {
    // failed to switch to WAKEUP_REQUEST
    ShouldNotReachHere();
    return;
  }

  while (true) {
    if (sr_notify(osthread) == 0) {
      if (sr_semaphore.timedwait(2)) {
        if (osthread->sr.is_running()) {
          return;
        }
      }
    } else {
      ShouldNotReachHere();
    }
  }

  guarantee(osthread->sr.is_running(), "Must be running!");
}

void SuspendedThreadTask::internal_do_task() {
  if (PosixSignals::do_suspend(_thread->osthread())) {
    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
    do_task(context);
    PosixSignals::do_resume(_thread->osthread());
  }
}

int PosixSignals::init() {
  // initialize suspend/resume support - must do this before signal_sets_init()
  if (SR_initialize() != 0) {
    vm_exit_during_initialization("SR_initialize failed");
    return JNI_ERR;
  }

  signal_sets_init();

  // Initialize data for jdk.internal.misc.Signal and BREAK_SIGNAL's handler.
  if (!ReduceSignalUsage) {
    jdk_misc_signal_init();
  }

  install_signal_handlers();

  return JNI_OK;
}
