13

Here is the code on which I set my handler for SIGABRT signal then I call abort() but handler does not get trigered, instead program gets aborted, why?

#include <iostream>
#include <csignal>
using namespace std;
void Triger(int x)
{
    cout << "Function triger" << endl;
}

int main()
{
    signal(SIGABRT, Triger);
    abort();
    cin.ignore();
    return 0;
}

PROGRAM OUTPUT:

enter image description here

codekiddy
  • 5,897
  • 9
  • 50
  • 80
  • Works perfectly here, after I include ``. Which platform? – Fred Foo Jan 19 '12 at 23:28
  • Windows 7 x64 with MSVC++ 2010 (no need to include cstdlib in visual studio) – codekiddy Jan 19 '12 at 23:29
  • 2
    Well, the program should be aborted unless the signal handlers does a `longjmp`. If you want the message to be printed before that, you might want to flush `std::cout` (or write to `std::cerr`). – Fred Foo Jan 19 '12 at 23:34

3 Answers3

19

As others have said, you cannot have abort() return and allow execution to continue normally. What you can do however is protect a piece of code that might call abort by a structure akin to a try catch. Execution of the code will be aborted but the rest of the program can continue. Here is a demo:

#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <iostream>

jmp_buf env;

void on_sigabrt (int signum)
{
  signal (signum, SIG_DFL);
  longjmp (env, 1);
}

void try_and_catch_abort (void (*func)(void))
{
  if (setjmp (env) == 0) {
    signal(SIGABRT, &on_sigabrt);
    (*func)();
    signal (SIGABRT, SIG_DFL);
  }
  else {
    std::cout << "aborted\n";
  }
}    

void do_stuff_aborted ()
{
  std::cout << "step 1\n";
  abort();
  std::cout << "step 2\n";
}

void do_stuff ()
{
  std::cout << "step 1\n";
  std::cout << "step 2\n";
}    

int main()
{
  try_and_catch_abort (&do_stuff_aborted);
  try_and_catch_abort (&do_stuff);
}
  • Seems this answer is unfinished. Note: ? – stanm Sep 08 '16 at 09:47
  • 2
    This is not portable. E.g. busybox+musl (Alpine 3.8) segfaults on a second call to abort(). Try to avoid abort() in production code (e.g. use compiler flag -DNDEBUG to avoid asserts). – rockdaboot Nov 19 '18 at 15:51
  • @rockdaboot I agree about the portability. However, I don't think that using `-DNDEBUG` is a solution. The best is to fix the actual code that generates the `abort()` call in the first place. – Alexis Wilke Dec 30 '22 at 05:15
10

Although you can replace handler for SIGABRT and abort() will pay attention to the handler, the abort is only inhibited if the signal handler does not return. The relevant quote in C99 is in 7.20.4.1 paragraph 2:

The abort function causes abnormal program termination to occur, unless the signal SIGABRT is being caught and the signal handler does not return. ...

Your signal handler does return and thus the program is aborted.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • So you're saying that the try_and_catch_abort above will only work in debug mode, and not for released code? – Michele Oct 22 '15 at 15:16
4

You get those symptoms i.e. the popup debug dialog, when you have a debug build (with windows and Visual Studio- I'm testing with 2012 version), since it sets a debug break, in the debug implementation of abort() ). If you pick "ignore" you get that message "Function triger"

If you do a release build, then you don't get the debug popup dialog, and you get the message, as expected

user2495422
  • 101
  • 1