Search code examples
c++linuxsignals

Exception Handling in Linux


I've been studying exception handling in Linux. I'm aware (to some extent) of the signal mechanism used by Linux to notify processes of SIGSEGV, SIGFPE, SIGINT etc. To trap these signals, they need to be explicitly registered using the sigaction.

My questions:

  1. Is there a 'catch-all' exception handler? Using the signal mechanism, I need to explicitly register for the signals. But I want to capture all signals, and ensure that wherever I can, I'd show a message to user and the app just doesn't quit. And get some logs for diagnosis. Windows has a 'catch-all' exception handler set using SetUnhandledExceptionHandler. Does Linux have something similar?
  2. From what I've read so far, signals seem to be the only way to capture exceptions (like SIGINT, SIGSEGV, SIGFPE etc.). In case I need to use signals, what should the behavior be? If main thread raises SIGSEGV, then it will be stuck in a loop (code which raised SIGSEGV <-> exception handler) and will I get to show some message to user? If a worker thread (created by app) hits a SIGSEGV, then I intend to kill the worker thread (therefore avoiding the loop) and signal the main thread to show a message to user and unwind gracefully.

I intend to use GTK for the app's UI (including the message screen). I'm looking for a Linux recommended way to handle exceptions and exit gracefully, to provide a good user experience.


Solution

  • I want to capture all signals

    No you don't. Or at least you shouldn't.

    Signals are:

    • technical stuff (if you intercept those, things may break):
      • HUP, TRAP, PIPE, ALRM, CHLD, WINCH, RT*
    • crashes (you are probably interested in these):
      • SEGV, BUS, FPE, ILL
      • possibly ABRT
    • user/system interactions (may be bad manners to intercept):
      • INT, QUIT, TERM, TSTP, PWR

    show a message to user and the app just doesn't quit

    It's somewhat possible. But if you have a multithreaded program that has just corrupted its memory, the best place to display that message may be from a different process. Some kind of external monitoring process as @Eljay suggests in comments.

    I intend to kill the worker thread (therefore avoiding the loop) and signal the main thread to show a message to user and unwind gracefully

    If you have a multithreaded program where a worker thread held some locks and you kill it, you're not getting those locks back. Trying to do anything non-trivial in the same process (even in different threads) will likely end up in a deadlock/further crashes.

    The most you can do in that handler is record what information you can in as simple way as possible (signal safety reminder) and then poke your monitoring process that its time has come.

    Or exec a helper program that will replace your crashed process and display the collected information to the user.

    If you are working with documents, should you try to save some data if you can? Assume things are corrupted/broken. So usually not.

    Anyway, you should ask yourself who this is for. Inexperienced users will get scared even with a friendly message. Experienced users may be happier if your application just crashes and they can look at it in a debugger. But the feature could be valuable for you if the dialog presents information that you want people to attach to bug reports.