How to Handle SIGABRT signal?
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);
}
SIGABRT handler. Do some cleanup before crash
You may restore the default SIGABRT behavior before catching it the second time :
void mysigabort(int signum)
{
// whatever you want
signal(signum, SIG_DFL);
kill(getpid(), signum); // or abort() ?
}
When does a process get SIGABRT (signal 6)?
abort()
sends the calling process the SIGABRT
signal, this is how abort()
basically works.
abort()
is usually called by library functions which detect an internal error or some seriously broken constraint. For example malloc()
will call abort()
if its internal structures are damaged by a heap overflow.
Keep running the program after SIGABRT c++ signal
I use a third library in my c++ program which under certain circumstances emits SIGABRT signal
If you have the source code of that library, you need to correct the bug (and the bug could be in your code).
BTW, probably SIGABRT
happens because abort(3) gets indirectly called (perhaps because you violated some conventions or invariants of that library, which might use assert(3) - and indirectly call abort
). I guess that in caffe the various CHECK*
macros could indirectly call abort
. I leave you to investigate that.
If you don't have the source code or don't have the capacity or time to fix that bug in that third party library, you should give up using that library and use something else.
In many cases, you should trust external libraries more than your own code. Probably, you are abusing or misusing that library. Read carefully its documentation and be sure that your own code calling it is using that library correctly and respects its invariants and conventions. Probably the bug is in your own code, at some other place.
I want to keep running my program
This is impossible (or very unreliable, so unreasonable). I guess that your program has some undefined behavior. Be very scared, and work hard to avoid UB.
You need to improve your debugging skills. Learn better how to use the gdb
debugger, valgrind, GCC sanitizers (e.g. instrumentation options like -fsanitize=address
, -fsanitize=undefined
and others), etc...
You reasonably should not try to handle SIGABRT
even if in principle you might (but then read carefully signal(7), signal-safety(7) and hints about handling Unix signals in Qt). I strongly recommend to avoid even trying catching SIGABRT
.
How to get signal to catch SIGABRT
The behaviour you describe is as documented.
From the Visual Studio documentation for abort (emphasis mine):
By default, when an app is built with the debug runtime library, the abort routine displays an error message before SIGABRT is raised. [...] To suppress the message, use _set_abort_behavior to clear the _WRITE_ABORT_MSG flag.
How to catch SIGABRT in multithread environment?
I need to catch SIGABRT, SIGSEGV and probably others signals to prevent my process from being killed
This is an exercise in futility. After SIGABRT
or SIGSEGV
is raised, you (in general) have no idea about the state of the process -- it may have corrupted heap, stack, global data internal to your test framework, global data internal to the C runtime system, etc. etc. Continuing such process is exceedingly likely to continue crashing at random (correct) places in the code.
The only sane way to handle this in a test framework is to fork
and have the parent process handle child error exits, report them and continue running additional tests.
SIGABRT is a thread direct signal ?
There is no such thing as "direct signal". SIGABRT
may be sent to the process from outside, or it can be raise
d inside the process.
What happens if I only use the main thread to catch the SIGABRT (or SIGSEGV) signal?
SIGSEGV
and SIGABRT
(when not sent from outside) is sent to the thread which caused the invalid memory operation (or raise
d it).
In addition, there is no way to "only use main thread" -- sigaction
is global across all threads (though you can set a thread-specific signal mask).
Related Topics
C++ Templates Angle Brackets Pitfall - What Is the C++11 Fix
Rewinding Std::Cout to Go Back to the Beginning of a Line
Difference Between Std::Result_Of and Decltype
Gnu C++ How to Check When -Std=C++0X Is in Effect
Using Hierarchy in Findcontours () in Opencv
Does New[] Call Default Constructor in C++
Why Does C++11 Have 'Make_Shared' But Not 'Make_Unique'
Boolean Values as 8 Bit in Compilers. Are Operations on Them Inefficient
C++ Method Only Visible When Object Cast to Base Class
Reset Cuda Context After Exception
C++11 Member Initializer List VS In-Class Initializer
Video Stabilization with Opencv
Questions About Hinnant's Stack Allocator
How to Use Valgrind with Python C++ Extensions
How to Alter a Float by Its Smallest Increment (Or Close to It)