static void crash_handler()

in watchman/SignalHandler.cpp [21:149]


static void crash_handler(int signo, siginfo_t* si, void*) {
  const char* reason = "";
  if (si) {
    switch (si->si_signo) {
      case SIGILL:
        switch (si->si_code) {
          case ILL_ILLOPC:
            reason = "illegal opcode";
            break;
          case ILL_ILLOPN:
            reason = "illegal operand";
            break;
          case ILL_ILLADR:
            reason = "illegal addressing mode";
            break;
          case ILL_ILLTRP:
            reason = "illegal trap";
            break;
          case ILL_PRVOPC:
            reason = "privileged opcode";
            break;
          case ILL_PRVREG:
            reason = "privileged register";
            break;
          case ILL_COPROC:
            reason = "co-processor error";
            break;
          case ILL_BADSTK:
            reason = "internal stack error";
            break;
        }
        break;
      case SIGFPE:
        switch (si->si_code) {
          case FPE_INTDIV:
            reason = "integer divide by zero";
            break;
          case FPE_INTOVF:
            reason = "integer overflow";
            break;
          case FPE_FLTDIV:
            reason = "floating point divide by zero";
            break;
          case FPE_FLTOVF:
            reason = "floating point overflow";
            break;
          case FPE_FLTUND:
            reason = "floating point underflow";
            break;
          case FPE_FLTRES:
            reason = "floating point inexact result";
            break;
          case FPE_FLTINV:
            reason = "invalid floating point operation";
            break;
          case FPE_FLTSUB:
            reason = "subscript out of range";
            break;
        }
        break;
      case SIGSEGV:
        switch (si->si_code) {
          case SEGV_MAPERR:
            reason = "address not mapped to object";
            break;
          case SEGV_ACCERR:
            reason = "invalid permissions for mapped object";
            break;
        }
        break;
#ifdef SIGBUS
      case SIGBUS:
        switch (si->si_code) {
          case BUS_ADRALN:
            reason = "invalid address alignment";
            break;
          case BUS_ADRERR:
            reason = "non-existent physical address";
            break;
        }
        break;
#endif
    }
  }

  if (si) {
    auto msg = folly::to<std::string>(
        "Terminating due to signal ",
        signo,
        " ",
        w_strsignal(signo),
        " generated by pid=",
        si->si_pid,
        " uid=",
        si->si_uid,
        " ",
        reason,
        " (",
        uintptr_t(si->si_value.sival_ptr),
        ")\n");
    ignore_result(write(STDERR_FILENO, msg.data(), msg.size()));
  } else {
    auto msg = folly::to<std::string>(
        "Terminating due to signal ",
        signo,
        " ",
        w_strsignal(signo),
        " ",
        reason,
        "\n");
    ignore_result(write(STDERR_FILENO, msg.data(), msg.size()));
  }

#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD)
  {
    void* array[24];
    size_t size = backtrace(array, sizeof(array) / sizeof(array[0]));
    backtrace_symbols_fd(array, size, STDERR_FILENO);
  }
#endif
  if (signo == SIGTERM) {
    w_request_shutdown();
    return;
  }
  // Resend the signal to terminate ourselves with it.
  // We register crash_handler with SA_RESETHAND so it will
  // not be invoked a second time.
  kill(getpid(), signo);
}