try/catch to avoid .stackdump - c++

In the code below i use try/catch in the python module code. In the try block i have a simple error (memory access violation) and trying to catch the corresponding exception and to terminate the program quietly without generation of the .stackdump file. However the latter is still generated what implies that try/catch construct does not do its job. How could i avoid generating .stackdump file and exit the program without errors when the improper operation (like one in the code) is met?
P.S. i'm compiling the code in cygwin with gcc and boost.python
It is interesting that it doesn't work only in case x[3]=2, but works for all other cases: e.g. x[4]=2 or x[20]=2 or, obviously, x[2]=2.
#include <boost/python.hpp>
#include <iostream>
#include <iomanip>
using namespace std;
using namespace boost::python;
class Hello
{
std::string _msg;
public:
Hello(std::string msg){_msg = msg;}
void run(){
try{
double* x;
x = new double[3];
x[3] = 2.0;
delete [] x;
}catch(...){ exit(0); }
}
};
BOOST_PYTHON_MODULE(xyz)
{
class_<Hello>("Hello", init<std::string>())
.def("run",&Hello::run)
;
}
EDIT:
According to what Maciek has suggested i tried the following trick:
Make signal handling function to throw an exception, but not exit
void sig_action(int signo) {
std::cout << "SIGNAL " << signo << std::endl;
throw 1;
// exit(0);
}
And now try to enclose a possibly problematic function in try/catch block (signal function is placed in class constructor):
class Hello
{
std::string _msg;
public:
Hello(std::string msg){
_msg = msg;
signal(SIGABRT, sig_action);
signal(SIGSEGV, sig_action);
}
void set(std::string msg) { this->_msg = msg; }
std::string greet() { return _msg; }
void run(){
try{
double* x;
x = new double[3];
x[3] = 2.0;
delete [] x;
}catch(...){ cout<<"error in function run()\n"; exit(0); }
}
};
However such a trick doesn't work as i expected it produces the following output:
SIGNAL 6
terminate called after throwing an instance of 'int'
SIGNAL 6
terminate called recursively
SIGNAL 6
terminate called recursively
....
(and many more times the same)
So the exception is thrown, but everything finishes before it has been caught. Is there any way to let it be caught before terminating the process?

You can only catch exceptions that are thrown. An invalid pointer access doesn’t throw an exception, it simply causes undefined behaviour, and in your particular case it results in a stack dump.
If you want to catch such a situation situation, use std::vector and the at function to access items. This will throw std::out_of_range when used with an invalid index. However, it’s usually better to avoid the possibility of such accesses a priori since they are usually indicative of a bug in your program, and bugs should not be handled via exceptions, they should be removed from the code.

On linux core dumps are generated by signal handlers with default action set to core (SIGABRT, SIGSEGV, ...). If you want to avoid core dump you can always capture/ignore those signals. It should work on Cygwin stackdumps as well. But you will still probably get some nasty message as output.
EDIT:
#include <signal.h>
// [...]
void sig_action(int signo) {
std::cout << "SIGNAL " << signo << std::endl;
exit(0);
}
int main(int argc, char* argv[]) {
signal(SIGABRT, sig_action);
signal(SIGSEGV, sig_action);
Hello h("msg");
h.run();
}

Related

Orphan code block throwing Exception in struct

I was recently asked this question in an interview. Below code, snippet behavior was asked. I mentioned that the code would
throw an exception that would be caught but it did not turn out to be the right answer.
I have tried debugging this piece of the code snippet and have two questions.
1.
If execution does enter the line try { A a; } then why catch fails to catch the exception?
2.
What is the behavior of this orphan piece of code that does not belong to any method inside the struct? If I put the orphan code
to be included under the constructor method of B i.e inside B() { } then the exception is caught properly. so how does the execution
flow handle this? I mean to which method/function stack does the orphan code try catch in B belong?
#include<iostream>
#include<string>
using namespace std;
struct A
{
A()
{
throw 2;
}
};
struct B
{
B()
// start of orphan code.
try
{
A a;
}
catch(int i)
{
cout << i << endl;
}
// end of orphan code.
};
int main(int argc, char* argv[])
{
B b;
cout << "3" << endl;
return(0);
}
What you call "orphan code" is in fact a function try block. Such blocks have a special behavior when used with constructors and destructors: every catch block implicitly rethrows the exception, as if the last statement were throw; . This is done to make it impossible to use an object that failed to complete construction.

Exception not caught after signal

I try to catch a termination signal to my code to write a restart file before exiting. My solution is based on this answer.
#include <exception>
#include <csignal>
#include <iostream>
class InterruptException : public std::exception
{
public:
InterruptException(int _s) : signal_(_s) { }
int signal() const noexcept
{
return this->signal_;
}
private:
int signal_;
};
/// method to throw exception at signal interrupt
void sig_to_exception(int s)
{
throw InterruptException(s);
}
int main()
{
// activate signal handling
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = sig_to_exception;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
try
{
for (std::size_t i = 0; i < 100000000; ++i)
{
std::cout << i << std::endl;
}
}
catch (const InterruptException& e)
{
std::cout << "Received signal " << e.signal() << std::endl;
std::exit(1);
}
catch(...)
{
std::cout << "Other catch!" << std::endl;
}
}
The exception gets thrown fine, however, my catch block does not catch it. The program terminates with an uncaught exception InterruptException. I tried with clang and gcc on MacOS. Any idea why the exception is not caught correctly?
Thanks
Output when compiled with g++ 7.3.0:
terminate called after throwing an instance of 'InterruptException'
what(): std::exception
Abort trap: 6
Output when compiled with Apple LLVM 9.0.0
libc++abi.dylib: terminating with uncaught exception of type InterruptException: std::exception
PS: It seems when I compile with Apple LLVM the exception gets caught sometimes, but not all the time, which makes this even weirder.
There is very little that you can reliably do in a signal handler. In particular, you cannot throw an exception. The code in the question (and the "answer" that it links to) relies, at best, on compiler/OS-specific behavior. For the limits on what you can do in a signal handler, see this.
Note that the link above refers to signal, which is standard C. sigaction is not standard C, it's POSIX, and the C++ language definition doesn't impose any requirements on a program that uses it.
On most system the stack frame used by the signal handler is not a standard function stack frame as defined by the compiler for function calls.
So throwing out of a sig handler is not supported.
Stack frame for signal handling in the Linux Kernel
From the discussion in the linked question, on a linux system they are not even using the same stack for the stack frame and returning requires jumping back to a system function to restore the original user stack.
Unless the OS is specifically designed to handle exceptions then this is not going to work.
The rule of thumb for signal handlers is to do as little as possible in a signal handler. Set a global flag that can be detected by your normal code then check that flag periodically in your normal code to see when the signal has happened.

Catch c++ exception by allocating c memory error

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.

How to cause C++ throw to dump core if the exception would be handled by a particular catch block

Is there a way to cause a throw in C++ to dump core at the throw site if the thrown exception would be handled by a certain catch block? I would like something similar to what happens with g++ when an exception reaches the top level.
For example, I would like something like this:
try {
bar();
try {
foo();
} catch(...) {
# pragma dump_at_throw_site
}
} catch(...) {
std::cerr << "There was a problem" << std::endl;
}
This way, if any exception thrown from foo() or its callee's that reaches the call-site of foo() would cause a core dump at the throw site so one can see who threw the exception that made it to the to this level.
On the other hand, exceptions thrown by bar() would be handled normally.
Yes,it can in Windows. I don't know Linux, suppose it can also.
We can register a Exception Handler function to response the throw before the catch
Here is the code example:
#include <iostream>
#include "windows.h"
#define CALL_FIRST 1
LONG WINAPI
VectoredHandler(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
std::cout <<"VectoredHandler"<<std::endl;
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
PVOID handler;
handler = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler);
try {
throw 1;
}catch(...)
{
std::cout <<"catch (...)"<< std::endl;
}
RemoveVectoredExceptionHandler(handler);
std::cout << "end of main"<<std::endl;
return 0;
}
The outputs of code are:
VectoredHandler
catch (...)
end of main
So,you can dump core int the function VectoredHandler.
The VectoredHandler is called after the debugger gets a first chance notification, but before the system begins unwinding the stack.
And if your purpose is just to debug the problem issue, then you can rely on the debugger feature to handle the first chance exception, don't need dump the application.
For your information, you may need know What is a First Chance Exception? in windows to understand how windows dispatch the exception.

why does throw "nothing" causes program termination?

const int MIN_NUMBER = 4;
class Temp
{
public:
Temp(int x) : X(x)
{
}
bool getX() const
{
try
{
if( X < MIN_NUMBER)
{
//By mistake throwing any specific exception was missed out
//Program terminated here
throw ;
}
}
catch (bool bTemp)
{
cout<<"catch(bool) exception";
}
catch(...)
{
cout<<"catch... exception";
}
return X;
}
private:
int X;
};
int main(int argc, char* argv[])
{
Temp *pTemp = NULL;
try
{
pTemp = new Temp(3);
int nX = pTemp->getX();
delete pTemp;
}
catch(...)
{
cout<<"cought exception";
}
cout<<"success";
return 0;
}
In above code, throw false was intended in getX() method but due to a human error(!) false was missed out. The innocent looking code crashed the application.
My question is why does program gets terminated when we throw "nothing”?
I have little understanding that throw; is basically "rethrow" and must be used in exception handler (catch). Using this concept in any other place would results into program termination then why does compiler not raise flags during compilation?
This is expected behaviour. From the C++ standard:
If no exception is presently being
handled, executing a throw-expression
with no operand calls
terminate()(15.5.1).
As to why the compiler can't diagnose this, it would take some pretty sophisticated flow analysis to do so and I guess the compiler writers would not judge it as cost-effective. C++ (and other languages) are full of possible errors that could in theory be caught by the compiler but in practice are not.
To elaborate on Neil's answer:
throw; by itself will attempt to re-raise the current exception being unwind -- if multiple are being unwound, it attempts to rethrow the most recent one. If none are being unwound, then terminate() is called to signal your program did something bogus.
As to your next question, why the compiler doesn't warn with throw; outside a catch block, is that the compiler can't tell at compile-time whether the throw; line may be executing in the context of a catch block. Consider:
// you can try executing this code on [http://codepad.org/pZv9VgiX][1]
#include <iostream>
using namespace std;
void f() {
throw 1;
}
void g() {
// will look at int and char exceptions
try {
throw;
} catch (int xyz){
cout << "caught int " << xyz << "\n";
} catch (char xyz){
cout << "caught char " << xyz << "\n";
}
}
void h() {
try {
f();
} catch (...) {
// use g as a common exception filter
g();
}
}
int main(){
try {
h();
} catch (...) {
cout << "some other exception.\n";
}
}
In this program, g() operates as an exception filter, and can be used from h() and any other function that could use this exception handling behavior. You can even imagine more complicated cases:
void attempt_recovery() {
try{
// do stuff
return;
} catch (...) {}
// throw original exception cause
throw;
}
void do_something() {
for(;;) {
try {
// do stuff
} catch (...) {
attempt_recovery();
}
}
}
Here, if an exception occurs in do_something, the recovery code will be invoked. If that recovery code succeeds, the original exception is forgotten and the task is re-attempted. If the recovery code fails, that failure is ignored and the previous failure is re-throw. This works because the throw; in attempt_recovery is invoked in the context of do_something's catch block.
From the C++ standard:
15.1 Throwing an exception
...
If no exception is presently being
handled, executing a throw-exception
with no operand calls terminate()
The reason the compiler can't reliably catch this type of error is that exception handlers can call functions/methods, so there's no way for the compiler to know whether the throw is occurring inside a catch. That's essentially a runtime thing.
I have little understanding that throw; is basically "rethrow" and must be used in exception handler (catch). Using this concept in any other place would results into program termination then why does compiler not raise flags during compilation?
Rethrowing is useful. Suppose you have a call stack three levels deep with each level adding some context resource object for the final call. Now, when you have an exception at the leaf level, you will expect some cleanup operation for whatever resources the object has created. But this is not all, the callers above the leaf may also have allocated some resources which will need to be deallocated. How do you do that? You rethrow.
However, what you have is not rethrow. It is a signal of giving up after some failed attempts to catch and process any and all exceptions that were raised.
A throw inside of a catch block with no args will re-throw the same exception that was caught, so it will be caught at a higher level.
A throw outside of a catch block with no args will cause a program termination.
To complete the previous answers with an example of when/why the compiler cannot detect the problem:
// Centralized exception processing (if it makes sense)
void processException()
{
try {
throw;
}
catch ( std::exception const & e )
{
std::cout << "Caught std::exception: " << e.what() << std::endl;
}
catch ( ... )
{
std::cout << "Caught unknown exception" << std::endl;
}
}
int main()
{
try
{
throw 1;
}
catch (...)
{
processException(); // correct, still in the catch clause
}
processException(); // terminate() no alive exception at the time of throw.
}
When compiling the function processException the compiler cannot know how and when it will be called.
You don't have anything to catch, and so the exception bubbles all the way up. Even catch(...) needs something.