gcc (GCC) 4.5.3
GNU gdb (GDB) 7.5.50.20130309-cvs (cygwin-special)
Netbeans 7.3
I have some trouble catching a SIGSEGV, Segment Fault Exception, in my code. A try-catch does not catch it (code below). Is this a non-catchable exception? Is there any way to catch it? (And of Course) What have I done wrong?
art
string SlipStringOp::dump(const SlipCell& X) const {
stringstream pretty;
PTR ptr = *getPtr(X);
pretty << "[string ] " << dumpLink(X) << " = "
<< setfill('0') << setw(8) << hex << ptr
<< " -> ";
try {
pretty << ptr->dump();
} catch(exception& e) {
pretty << e.what();
postError(SlipErr::E3023, "SlipStringOp::dump", "", "Deletion of cell deleted the pointer.");
} catch(...) {
postError(SlipErr::E3023, "SlipStringOp::dump", "", "Deletion of cell deleted the pointer.");
}
return pretty.str();
}; // string SlipStringOp::dump(const SlipCell& X) const
SIGSEGV is not an exception; it's a signal. Accessing an invalid memory address is known as a segmentation fault. When your program does this, the operating system will send your process the SIGSEGV signal. The default handler for this signal will immediately terminate the process.
You can intercept a signal, but this is not a signal you should be handling yourself. If your program is causing a segmentation fault, it has a bug, no doubt about it.
If you've isolated the segmentation fault to the pretty << ptr->dump(); line, I would guess that the problem is probably that ptr isn't pointing to a valid object. Alternatively, the dump function is doing something bad.
Do not attempt to fix this by handling the signal. Do fix this by making sure your program doesn't cause a segmentation fault.
There are two questions here. Firstly, why are you getting a SIGSEGV? There probably isn't enough code here for us to tell, but is your call to ptr->dump() calling the same function recursively? IF so, you have infinite recursion, and that is causing the seg fault.
Second question is how you trap the signal, and that's been answered by previous responders.
You throw an exception with a throw expression. You catch an exception in a catch clause.
You raise a signal by calling raise. You handle a signal by installing a handler before the exception is raised.
Any other actions and interactions are system-specific (i.e., not portable).
Related
I am just starting to learn C and installing now QT x64 (form here: http://tver-soft.org/qt64). I have two options to install: MinGW 4.9.2 SEH or MinGW 4.9.2 SJLJ.
Question: Which is better to install and why?
I read What is difference between sjlj vs dwarf vs seh? and https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH but understand nothing (new to C and compiller languages).
SJLJ and SEH are two different exception handling systems.
For the specific differences, the resources you've already seen cover everything.
However, as for which one is better to install, go with SJLJ unless you know that you need SEH.
2019 Update: On modern systems, there's no reason to use SJLJ, so the advice above should probably be flipped. SEH is more common now. Ultimately though, it doesn't really matter, since it's easy to switch between the two.
SJLJ
SJLJ is more widely supported across architectures, and is more robust. Also, SJLJ exceptions can be thrown through libraries that use other exception handling systems, including C libraries. However, it has a performance penalty.
SEH
SEH is much more efficient (no performance penalty), but unfortunately is not well-supported. SEH exceptions will cause bad things to happen when thrown through libraries that do not also use SEH.
As far as your code is concerned, there are no real differences. You can always switch compilers later if you need to.
I discovered one difference between SJLJ and SEH exception handling in MinGW-w64: C signal handlers set by signal() function do not work in SJLJ version as soon as at least one try{} block gets executed at the run time. Since this issue does not seem to be described anywhere, I am putting it here for the record.
The following example (test_signals.cpp) demonstrates this.
// This sample demonstrates how try {} block disables handler set by signal()
// on MinGW-w64 with GCC SJLJ build
#include <signal.h>
#include <iostream>
int izero = 0;
static void SIGWntHandler (int signum)//sub_code)
{
std::cout << "In signal handler, signum = " << signum << std::endl;
std::cout << "Now exiting..." << std::endl;
std::exit(1);
}
int main (void)
{
std::cout << "Entered main(), arming signal handler..." << std::endl;
if (signal (SIGSEGV, (void(*)(int))SIGWntHandler) == SIG_ERR)
std::cout << "signal(OSD::SetSignal) error\n";
if (signal (SIGFPE, (void(*)(int))SIGWntHandler) == SIG_ERR)
std::cout << "signal(OSD::SetSignal) error\n";
if (signal (SIGILL, (void(*)(int))SIGWntHandler) == SIG_ERR)
std::cout << "signal(OSD::SetSignal) error\n";
// this try block disables signal handler...
try { std::cout << "In try block" << std::endl; } catch(char*) {}
std::cout << "Doing bad things to cause signal..." << std::endl;
izero = 1 / izero; // cause integer division by zero
char* ptrnull = 0;
ptrnull[0] = '\0'; // cause access violation
std::cout << "We are too lucky..." << std::endl;
return 0;
}
Builds with:
g++ test_signals.cpp -o test_signals.exe
The expected output is:
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
In signal handler, signum = 8
Now exiting...
The actual output when I build with MigGW-w64 SJLJ variant is:
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
The application gets terminated silently after some delay. That is, signal handler does not get called. If try{} block is commented out, signal handler gets called properly.
When using MinGW-w64 SEH variant, it behaves as expected (signal handler gets called).
I do not have clear idea of why this problem occurs, thus will be grateful if someone can give an explanation.
I allocate a char pointer for receiving data. When the data is too large, I'll receive the Segmentation fault (core dumped). I try to use a try catch block to catch the exception to avoid this kind of error, but the same error still shows. How do I catch this kind of exception?
#include<iostream>
using namespace std;
void setmemory(char* p, int num)
{
p=(char*)malloc(num);
}
void test(void)
{
char* str = NULL;
setmemory(str,1);
try{
strcpy(str,"hello");
cout << "str:" << str << endl;
} catch (...) {
str = NULL;
cout << "Exception occured!" << endl;
}
}
int main()
{
test();
return 0;
}
Generally catching of Segmentation Fault is bad idea because you have no guaranty that any data in your program still valid. So you cannot just intercept SIGSEGV signal and do you work as usual.
See more details here:
How to catch segmentation fault in Linux?
You cannot catch segmentation fault through exception... Exceptions are not designed to catch signals. For these cases you need special handling like calling signal handler etc...
Although there is a way to convert these signals into exceptions in C++. Following link would illustrate on this topic:-
https://code.google.com/p/segvcatch/
Example given in this:-
try
{
*(int*) 0 = 0;
}
catch (std::exception& e)
{
std::cerr << "Exception catched : " << e.what() << std::endl;
}
Anyway after getting segmentation fault it's better to go for debugging rather than continue with current execution and later be transported to realm of undefined behavior.
You cannot catch a Segmentation fault in C++. A seg fault is a result of memory corruption due to a bad operation run by your program. At that point, the operating system has taken control of your program. You don't want to keep a program running after a seg fault because the state is unstable. You as the programmer need to avoid seg faults.
If the code you posted is your actual code, even if you allocated enough space, your code will not work correctly.
void setmemory(char *p, int num)
{
p=(char*)malloc(num);
}
int main()
{
char* str = NULL;
setmemory(str,1);
//...
strcpy(str,"hello");
We can stop right there. You are attempting to copy "hello" to a NULL pointer. You are not setting str to the allocated space, even though the setmemory function was called.
The proper way to do this (I will use the malloc, even though I don't recommend it) would be:
void setmemory(char *&p, int num)
{
p=(char*)malloc(num);
}
You need to pass the pointer by reference, otherwise p acts as a temporary variable, so setting p within the function will not propagate back to the caller.
There is a CRASH in Function() due to some exceptions so, throw X would not be called. In this case how to call catch block to handle exceptions?
NOTE: we can't modify the code in Function() definition
Sample code:
cout << "Before try \n";
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}
catch (...) {
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
So can anyone help me out for this?
A "CRASH" is not an exception. It is Undefined Behaviour. Absolutely anything could have happened. You are lucky that the system detected it. It could have formatted your disk or summoned daemons out of your nose. Instead the system is only shutting down the process to prevent further damage.
The system might even be so kind as to let you define what to do instead of shutting down the process. The way to define it is system specific. In Unix, you need to install signal handler (the advanced way), in Windows you use structural exceptions.
But the problem is that if the function crashed, there is no way to tell how big mess it left the memory of the process in. You really have to fix the crash. A crash is always a bug.
The fact that a crash is inside that function does not automatically mean the bug is in that function. Most crashes I've seen happened in standard library functions, but they were not bugs in standard library. They were caused by incorrect use of those functions, or sometimes incorrect use of something different much earlier in the program. Because when you invoke Undefined Behaviour, there's no telling when it will cause a crash. Especially buffer overruns and writes to uninitialized pointers tend to cause crashes eventually when some unrelated code wants to use the variable that was overwritten.
That said if the bug is indeed in that function and you can't modify it, you will have to get somebody who can or find an alternative that works better. Because there's no way the program is going to work correctly otherwise.
There's an aditional '}' in the try block in your code. Not sure whether that was an error in typing the code or from another higher level block.
The catch(...){} block will be executed when any unhandled exception is thrown inside the try {} block. It doesn't matter whether the exceptions are thrown directly under the block or somewhere deep down in other function calls in the block.
cout << "Before try \n";
try
{
abc->Function1(); //A potential for crash
abc->Function2(); //Another potential for crash
abc->Function3(); //Another potential for crash
// Do some checks and throw an exception.
throw x;
cout << "After throw (Never executed) \n";
}
catch (...)
{
// This will catch all unhandled exceptions
// within the try{} block. Those can be from
// abc->Function1(), abc->Function2(), abc->Function3(),
// or the throw x within the block itself.
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
Hope that is helpful.
Here us the meaning of try and catch
try {
//[if some ABC type exception occur inside this block,]
}catch (ABC) {
//[Then, Do the things inside this block.]
}
So
after the exception occur in your abc->Function(); flow will directly jump in to catch block so write there what you need to do. as example.
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}catch (Exception ex) {
cout << "Exception Caught \n";
throw ex;
}
actually throw x; doesn't have any use here. because if your abc->Function(); worked fine, then it will throw an exception. so just remove that line.
the code you have written works exactly true . the compiler when see the throw command every where in the try{} it will go to the catch(){} so the cout << "After throw (Never executed) \n"; won't execute and then the code after the catch(){} will execute
for reading more about this case here is the link trycatch
If you got exception ,
abc->Function(); //Here is CRASH
You will enter in catch(...) block.
If you are using Windows OS, for OS generated exceptions you also need to use __try/__catch
Can an ellipsis try-catch be used to catch all the errors that can lead to a crash? Are there are any anomalies?
try
{
//some operation
}
catch(...)
{
}
No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.
You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).
If the code inside try/catch block crashed somehow, the program is anyway in a non-recoverable state. You shouldn't try to prevent the crash, the best that the program can do is just let the process crash.
The "anomaly" is in the fact that your code only catches the exceptions, and not the errors. Even if the code is exception-safe (which may be not the case, if you are trying to work-around its mistakes by a try/catch block), any other inner error may bring the program into irrecoverable state. There is simply no way to protect the program from it.
Addition: look at this article at "The Old New Thing" for some insights.
It is the Catch All handler.
It catches all the C++ exceptions thrown from the try block. It does not catch segfault and other signals that cause your program to crash.
While using it, You need to place this handler at the end of all other specific catch handlers or it all your exceptions will end up being caught by this handler.
It is a bad idea to use catch all handler because it just masks your problems and hides the programs inability by catching all(even unrecognized) exceptions. If you face such a situation you better let the program crash, and create a crash dump you can analyze later and resolve the root of the problem.
It catches everything that is thrown, it is not limited to exceptions. It doesn't handle things like windows debug asserts, system signals, segfaults.
TEST(throw_int) {
try {
throw -1;
} catch (std::exception &e) {
std::cerr << "caught " << e.what() << std::endl;
} catch (...) {
std::cerr << "caught ..." << std::endl;
}
}
Throwing an integer isn't really recommended though. It's better to throw something that inherits from std::exception.
You might expect to see something like this as a last ditch effort for documenting failure, though. Some applications aren't required to be very robust. Internal tools might cost more than they are worth if you went through the paces of making them better than hacked together crap.
int main(int argc, char ** argv) {
try {
// ...
} catch (std::exception &e) {
std::cerr << "error occured: " << e.what() << std::endl;
return 1;
}
return 0;
}
I try to inject the exception to thread using signals, but some times the exception is not get caught. For example the following code:
void _sigthrow(int sig)
{
throw runtime_error(strsignal(sig));
}
struct sigaction sigthrow = {{&_sigthrow}};
void* thread1(void*)
{
sigaction(SIGINT,&sigthrow,NULL);
try
{
while(1) usleep(1);
}
catch(exception &e)
{
cerr << "Thread1 catched " << e.what() << endl;
}
};
void* thread2(void*)
{
sigaction(SIGINT,&sigthrow,NULL);
try
{
while(1);
}
catch(exception &e)
{
cerr << "Thread2 catched " << e.what() << endl; //never goes here
}
};
If I try to execute like:
int main()
{
pthread_t p1,p2;
pthread_create( &p1, NULL, &thread1, NULL );
pthread_create( &p2, NULL, &thread2, NULL );
sleep(1);
pthread_kill( p1, SIGINT);
pthread_kill( p2, SIGINT);
sleep(1);
return EXIT_SUCCESS;
}
I get the following output:
Thread1 catched Interrupt
terminate called after throwing an instance of 'std::runtime_error'
what(): Interrupt
Aborted
How can I make second threat catch exception?
Is there better idea about injecting exceptions?
G++ assumes that exceptions can only be thrown from function calls. If you're going to violate this assumption (eg, by throwing them from signal handlers), you need to pass -fnon-call-exceptions to G++ when building your program.
Note, however that this causes G++ to:
Generate code that allows trapping instructions to throw
exceptions. Note that this requires platform-specific runtime
support that does not exist everywhere. Moreover, it only allows
_trapping_ instructions to throw exceptions, i.e. memory
references or floating point instructions. It does not allow
exceptions to be thrown from arbitrary signal handlers such as
`SIGALRM'.
This means that exceptioning out from the middle of some random code is NEVER safe. You can only except out of SIGSEGV, SIGBUS, and SIGFPE, and only if you pass -fnon-call-exceptions and they were triggered due to a fault in the running code. The only reason this worked on thread 1 is because, due to the existence of the usleep() call, G++ was forced to assume that it might throw. With thread 2, G++ can see that no trapping instruction was present, and eliminate the try-catch block.
You may find the pthread cancellation support more akin to what you need, or otherwise just add a test like this somewhere:
if (*(volatile int *)terminate_flag) throw terminate_exception();
In Boost.thread a thread can be interrupted by invoking the interrupt() member function of the corresponding boost::thread object. It uses pthread condition variables to communicate with the thread and allows you to define interruption points in the thread code. I would avoid use of pthread_kill in C++. The fact that boost thread doesn't use pthread_kill anywhere in their code confirms this I think.