How to Catch Segmentation Fault in Linux

How to catch segmentation fault in Linux?

On Linux we can have these as exceptions, too.

Normally, when your program performs a segmentation fault, it is sent a SIGSEGV signal. You can set up your own handler for this signal and mitigate the consequences. Of course you should really be sure that you can recover from the situation. In your case, I think, you should debug your code instead.

Back to the topic. I recently encountered a library (short manual) that transforms such signals to exceptions, so you can write code like this:

try
{
*(int*) 0 = 0;
}
catch (std::exception& e)
{
std::cerr << "Exception caught : " << e.what() << std::endl;
}

Didn't check it, though. Works on my x86-64 Gentoo box. It has a platform-specific backend (borrowed from gcc's java implementation), so it can work on many platforms. It just supports x86 and x86-64 out of the box, but you can get backends from libjava, which resides in gcc sources.

Catch Segmentation fault in c++

C++ try-catch blocks only handle C++ exceptions. Errors like segmentation faults are lower-level, and try-catch ignores these events and behaves the same as if there was no try-catch block.

Is it possible to catch a segfault with try/catch?

No you can`t.

A SEGFAULT isn't a regular exception.

The code you show is simply undefined behavior, and anything may be happen. There's no guarantee it ends up throwing an exception.

How to recover from segmentation fault on C++?

I suggest that you create a very small program that you make really safe that monitors the buggy program. If the buggy program exits in a way you don't like, restart the program.

Posix example:

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <cstdio>
#include <iostream>

int main(int argc, char* argv[]) {
if(argc < 2) {
std::cerr << "USAGE: " << argv[0] << " program_to_monitor <arguments...>\n";
return 1;
}

while(true) {
pid_t child = fork(); // create a child process

if(child == -1) {
std::perror("fork");
return 1;
}

if(child == 0) {
execvp(argv[1], argv + 1); // start the buggy program
perror(argv[1]); // starting failed
std::exit(0); // exit with 0 to not trigger a retry
}

// Wait for the buggy program to terminate and check the status
// to see if it should be restarted.

if(int wstatus; waitpid(child, &wstatus, 0) != -1) {
if(WIFEXITED(wstatus)) {
if(WEXITSTATUS(wstatus) == 0) return 0; // normal exit, terminate

std::cerr << argv[0] << ": " << argv[1] << " exited with "
<< WEXITSTATUS(wstatus) << '\n';
}
if(WIFSIGNALED(wstatus)) {
std::cerr << argv[0] << ": " << argv[1]
<< " terminated by signal " << WTERMSIG(wstatus);
if(WCOREDUMP(wstatus)) std::cout << " (core dumped)";
std::cout << '\n';
}
std::cout << argv[0] << ": Restarting " << argv[1] << '\n';
} else {
std::perror("wait");
break;
}
}
}

I get a segmentation fault instead of an exception

Since segfaults are not caused (directly) the the software, but rather by the processor detecting that you are trying to access invalid memory (or access memory in an invalid way - e.g writing to memory that is write-protected, executing memory that isn't supposed to be executed, etc), it is not "catchable" with try/catch, which is designed to catch software that throws an exception. They are both called exceptions, but they originate at different levels of the software/hardware of the system.

Technically, you can catch segfaults with a signal handler for SIGSEGV. However, as Ivaylo explains, it's is not, typically, allowed to just "try again" if you get a segfault. The signal hander for SIGSEGV is allowed to longjmp or exit, but shouldn't just return.

Read more about signals here:
http://www.alexonlinux.com/signal-handling-in-linux

Typical C++ exceptions (result of throw) can be retried without problem (of course, the same exception may be thrown again, of course.

Segmentation fault handling

The default action for things like SIGSEGV is to terminate your process but as you've installed a handler for it, it'll call your handler overriding the default behavior. But the problem is segfaulting instruction may be retried after your handler finishes and if you haven't taken measures to fix the first seg fault, the retried instruction will again fault and it goes on and on.

So first spot the instruction that resulted in SIGSEGV and try to fix it (you can call something like backtrace() in the handler and see for yourself what went wrong)

Also, the POSIX standard says that,

The behavior of a process is undefined after it returns normally from
a signal-catching function for a [XSI] SIGBUS, SIGFPE, SIGILL, or
SIGSEGV signal that was not generated by kill(), [RTS] sigqueue(),
or raise().

So, the ideal thing to do is to fix your segfault in the first place. Handler for segfault is not meant to bypass the underlying error condition

So the best suggestion would be- Don't catch the SIGSEGV. Let it dump core. Analyze the core. Fix the invalid memory reference and there you go!

try catch fails to handle segmentation fault inside a pthread

Instead of using the operator[] (which does not perform bounds checking) and will result in undefined behavior if the vector does not have an element at the specified index, you can use the at() member function.

at( size_type pos );

This function:

  • Returns a reference to the element at specified location pos, with bounds checking.

  • If pos is not within the range of the container, an exception of type std::out_of_range is thrown.

Since an exception is thrown with at(), you can catch it.

The usage in your case will be:

int firing_crash=cdp->firing_data.at(0).size();

Try/Catch a segmentation fault on Linux

If you have a scenario where many pointers across your app reference the same limited-lifetime objects, a popular solution is to use boost smart pointers. Edit: in C++11, both of these types are available in the standard library

You would want to use shared_ptr for pointer(s) that are responsible for the lifetime of your object and weak_ptr for the other pointers, which may become invalid. You'll see that weak_ptr has the validity check you're asking for built in.



Related Topics



Leave a reply



Submit