0

I need to catch segmentation fault and other unknown exceptions in my application. But I do not know how I can do that! Can I use std::uncaught_exceptions for this aim?

Sam Mokari
  • 461
  • 3
  • 11
  • No can do. Segfault is generated below C++. It's not an exception or even a C++ thing. – user4581301 Jan 18 '17 at 05:10
  • You might want to read: http://stackoverflow.com/questions/457577/catching-access-violation-exceptions – Mikel F Jan 18 '17 at 05:13
  • 6
    You need to catch it and do *what* exactly? This is not really something you can safely recover from. SEGV means your code is seriously broken somehow, you should probably invest effort into fixing the root cause. – paxdiablo Jan 18 '17 at 05:14
  • What do you mean by "avoiding?" `std::uncaught_exception` just tells you there are exceptions outstanding. It doesn't do anything about them. – user4581301 Jan 18 '17 at 05:32
  • 1
    With all due respect, if you understood what a segmentation fault was, you would not be asking this question. – Joe C Jan 18 '17 at 07:05
  • @user4581301 Why it's not a C++ thing? It's a signal, isn't it? – HolyBlackCat Jan 18 '17 at 07:51
  • @HolyBlackCat , I could have worded that better. Signals are C++. The segfault signal is a C++ representation of a memory error detected by a memory manager that's most likely implemented in hardware and well below the C++ runtime. This error is often catastrophic and means the program can no longer be trusted. Who knows what valid memory may have been corrupted before an out of bounds access was detected? – user4581301 Jan 18 '17 at 12:51
  • @user4581301 .. the "signal" is actually a CPU interrupt that the OS has a callback into and then make a call to any other call backs that were registered by the `std::signal` call. `std::signal` is part of the standard, but just because it's "there" doesn't necessarily mean the CPU or OS will implement the specific library calls that the C++ (or C) standard library use. So you might register a handler with `std::signal` on a QNX system, but the OS could just ignore it if the CPU the system is on doesn't have any sort of interrupt handlers (possible on embedded systems). – txtechhelp Jan 19 '17 at 02:06
  • @txtechhelp Agreed, but the C++ standard guarantees the same behaviour of `std::signal` regardless of what is underneath, if anything. That's the part that is C++. What happens to raise a segfault, if such a thing is even possible on the platform, is not C++. It's below C++. – user4581301 Jan 19 '17 at 02:23

1 Answers1

1

Can I use std::uncaught_exceptions for this aim?

Consider this code:

int main(int argc, char* argv[])
{
    int *val = NULL;
    *val = 1;
    std::cout << "uncaught: " << std::uncaught_exceptions() << std::endl;
    return 0;
}

This will likely cause a segmentation fault and nothing will be output.

I need to catch segmentation fault and other unknown exceptions in my application. But I do not know how I can do that!

Exception handling in C++ can be done through the try-catch block, and you could use the std::signal function to catch certain errors like SIGSEGV, SIGFPE, or SIGILL, example:

#include <iostream>
#include <exception>
#include <csignal>
#include <cstdio>

extern "C" {
    void sig_fn(int sig)
    {
        printf("signal: %d\n", sig);
        std::exit(-1);
    }
}

int main(int argc, char* argv[])
{
    int *val = NULL;
    std::signal(SIGSEGV, sig_fn);
    try {
        *val = 1;
    } catch (...) {
        std::cout << "..." << std::endl;
    }
    if (std::uncaught_exception()) {
        std::cout << "uncaught" << std::endl;
    }
    std::cout << "return" << std::endl;
    return 0;
}

But you should note that this type of exception handling is really meant to do clean-up and shutdown, not necessarily catch and release; take this code for example:

#include <iostream>
#include <exception>
#include <csignal>
#include <cstdio>

extern "C" {
    void sig_fn(int sig)
    {
        printf("signal: %d\n", sig);
    }
}

int main(int argc, char* argv[])
{
    int *val = NULL;
    std::signal(SIGSEGV, sig_fn);
    while (true) {
        try {
            *val = 1;
        } catch (...) {
            std::cout << "..." << std::endl;
        }
    }
    if (std::uncaught_exception()) {
        std::cout << "uncaught" << std::endl;
    }
    std::cout << "return" << std::endl;
    return 0;
}

This code will cause and catch the segmentation fault forever!

If you are trying to catch a segmentation fault, you need to investigate why the segmentation fault (or any error for that matter) happened in the first place and correct that issue; using the above code as an example:

int *val = NULL;
if (val == NULL) {
    std::cout << "Handle the null!" << std::endl;
} else {
    *val = 1;
}

For further reading: here is a SO Q&A on what a segfault is, as well, here is the Wiki on it, and MIT has some tips on handling and debugging segfaults too.

Hope that can help.

Community
  • 1
  • 1
txtechhelp
  • 6,625
  • 1
  • 30
  • 39
  • The first example is undefined behaviour according to the C++ standard. It will probably result in a segfault on every system you'll encounter in your carer as a programmer, but no guarantees. – user4581301 Jan 18 '17 at 12:59
  • @user4581301 .. technically all of the examples are UB since all of them dereference a null pointer; but given the OP's knowledge of exceptions and signals, I was more trying to express that the OP should see that as an error (instead of just UB); I did change the _always_ to _likely_ .. because this code: `int *v = NULL; try { *v = 1; } catch (...) { std::cout<<"..."< – txtechhelp Jan 19 '17 at 02:01