bitwiseworks / libc

LIBC Next (kLIBC fork)
9 stars 4 forks source link

Change defalt SIGTRAP action to terminate + "core dump" #111

Closed dmik closed 3 years ago

dmik commented 3 years ago

SIGTRAP is what LIBC generates in response to raising XCPT_BREAKPOINT with DosRaiseException or simply execting int 3. The default handler for this signal in LIBC is process termination. In practice this means that the program just silently exits with no information about what happened (unless it is run under the debugger which is set up to intercept XCPT_BREAKPOINT).

However, according to many sources (1, 2) , the default SIGTRAP action on Linux and BSD is not only to terminate the process but also generate a core dump. We don't have core dumps but LIBC had always provided a mini dump of the registers and some thread information to the console. Recently we improved it by generating a nice EXCEPTQ trap report instead (see #96, #98). This is what happens by default on signals such as SIGSEGV, SIGFPE and others which are programmed to generate a core dump by default on Posix systems (so our .TRP is a sort of a "core dump"). It sounds logical to make SIGTRAP behave the same way in our LIBC too.

I faced this when dealing with LIBC assert statements (end up in a call to __libc_LogAssert) which are also used in LIBCx. __libc_LogAssert prints some information to the console but then it just terminates the process due to XCPT_BREAKPOINT (unless LIBC_STRICT_DISABLED is set in the environment to any value). This is not very useful as the assertion information is not enough to locate the problem. An EXCEPTQ report is highly wanted but it's not generated due to the default signal action. See https://github.com/bitwiseworks/qtwebengine-chromium-os2/issues/43.

dmik commented 3 years ago

Making it all work in a test app was easy but then I faced a strange problem in Chromium, this code:

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] = {
      SIGHUP,  SIGINT,  SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
      SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};
  for (unsigned i = 0; i < base::size(signals_to_reset); i++) {
    CHECK_EQ(0, sigaction(signals_to_reset[i], &sigact, NULL));
  }

fails like that:

[0724/000422.223000:FATAL:main.cc(108)] Check failed: 0 == sigaction(signals_to_reset[i], &sigact, __null) (0 vs. -1)

I need to sort that out.

dmik commented 3 years ago

The problem in Chromium is a false alarm — some accidental modification when saving the file (which killed SIGABRT). Gone after fixing.