System exception handling on different platforms - c++

Basically, how to catch exceptions on mac/linux? That is, exceptions, that are not intrinsic to the language, like segfaults & integer division. Compiling on MSVC, __try __except is perfect because the stack handling allows to catch exceptions and continue execution lower down the stack.
Now, i would like to extend my program to other platforms (mainly the ones mentioned), but i have no idea how exception handling works on these platforms work. As far as i understand, it's handled through posix signals? And as of such, wont allow to handle exception and continue lower down the stack?
Edit: Would this be valid (pseudo code)? As i see it, i leave C++ blocks correctly and thus dont indulge myself in UB.
jmp_buf buffer;
template< typename func >
protected_code(func f) {
if(!setjmp(buffer) {
f();
}
else
{
throw std::exception("exception happened in f()"):
}
}
void sig_handler() {
longjmp(buffer);
}
int main() {
sigaction(sig_handler);
try {
protected_code( [&]
{
1/0;
}
);
}
catch(const std::exception & e) {
...
}
}
Edit 2:
Wow for some reason i never thought of just throwing a C++ exception from the signal handler, no need to use longjmp/setjmp then. It of course relies on the fact that the thread calling the signal handler is the same stack and thread that faulted. Is this defined/guaranteed somewhere?
Code example:
void sig_handler(int arg) {
throw 4;
}
int main() {
signal(SIGFPE, sig_handler);
try {
int zero = 1;
zero--;
int ret = 1/zero;
} catch(int x) {
printf("catched %d\n", x);
}
return 0;
}

In Unix, you'd catch processor faults with signal handlers, using the sigaction function to install a suitable handler for the signal that you want to handle.
(I think you mean __try ... __except rather than __try ... __catch.

Related

Nested catch operators

I need catch exceptions that are maybe thrown by code in try...catch construction, and do something depending on exception type. But also I want do some code if any exception are thrown.
I did so:
try
{
// code
}
catch (...)
{
try
{
throw;
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
// here is code that are executed if any exception are thrown
}
My code works, but I want to know whether the Standard says anything about it.
Maybe is there any better method?
UPD: Sorry for the slow answers to comments. Simple, English is a second language for me.
UPD: I think that code from AdelNick or second code from Steve Jessop or second code from David Rodríguez - dribeas are right for me.
Your approach is bad, because the // here is code that are executed if any exception are thrown part won't be executed if neither of exc1 or exc2 branch catch the exception. Your code is an equivalent version of the following:
try
{
// code
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
// here is code that are executed if any exception are thrown
The C++ language does not support a finally block, if that's what you're after. That is because an object's destructor is responsible for freeing resources, not a finally block. Here is Stroustrup's explanation of the topic.
You should write:
try
{
// code
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
catch (...)
{
// here is code that are executed if any *other* exception are thrown
}
If you want particular code to be executed as part of all three cases then you have two options: call it in all three places, or do something like this:
bool threw = true;
try
{
// code
threw = false;
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
catch (...) {
}
if (threw) {
// here is code that are executed if any exception are thrown
}
I would change the code order as following:
try
{
try
{
// code
}
catch (exc1)
{
// handling
throw; // edited. was: throw exc1;
}
catch (exc2)
{
// handling
throw; // edited. was: throw exc2;
}
}
catch(...)
{
// here is code that are executed if any exception are thrown
}
as it works if any other type of exception is thrown (not only exc1 or exc2). Also if the code common for all exceptions is the resource releasing, consider using RAII principle instead).
Looking at the comments it seems that you may be expecting something that won't happen, and that has already been discussed in other answers. But it could be a misunderstanding on our side. If the code inside the try can only throw one of exc1 or exc2 then yes, it will do what you expect.
From the comment update, it seems that the intention was to handle any exception, including those that are neither exc1 nor exc2. For that purpose, the code won't do what is expected and exc3 will propagate outside of the nested trys. Just flatten the two levels and add a catch (...) at the end.
From here on the answer was based on a false assumption about the question.
The pattern of rethrowing is supported by the standard and used commonly in situations where the handling of the exceptions in different contexts is the same to avoid code duplication:
void processException() {
// implement exception handling in all contexts
try {
throw;
} catch (exceptionType1 const & ex1) {
} catch (exceptionType2 const & ex2) {
// } catch (...) {
}
}
void f() {
try {
something();
} catch (...) {
processException();
}
}
void g() {
try {
anotherThing();
} catch (...) {
processException();
}
}
If the code to handle the exceptions is not going to be centralized for different functions, that pattern may complicate the code more than you need. You could consider a single try/catch with an extra control variable:
bool success = false;
try {
doSomething();
success = true;
} catch (exception1 const & ex1) {
...
} catch (exception2 const & ex2) {
...
// } catch (...) {
}
if (!success) {
// common code to all exceptions
}

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.

Notifying user of Access Violation like Exceptions

I have a multi-threaded application for retrieving database information and storing data as linked list of objects which i use further to do some operations on them and output the results. During the course of execution, I am bound to encounter exceptions like Access Violation due to the nature of pointers.
I certainly know these exceptions (Hardware or Software) are not caught by regular try catch in C++ and also know that we have avoid such exceptions by reprogramming culprit section.. But because i dont have control of data in database, sometimes I end up getting the exception and whole program crashes.
I would like to know if there a way to notify the user of Access Violation and preventing the affected thread from crashing other threads or whole process.
int ex;
pthread_mutex_t lk;
void sighandler(int a){
pthread_mutex_unlock(&lk);
}
static void *func1(void * arg) {
while(1) {
pthread_mutex_lock(&lk);
if(ex<=0) {
try {
char *p=0;*p = 0;
} catch(...) {
printf("eerr");
}
pthread_mutex_unlock(&lk);
break;
}
ex--;
pthread_mutex_unlock(&lk);
}
return 0;
}
static void *func2(void * arg) {
while(1) {
pthread_mutex_lock(&lk);
if(ex<=-100) {
pthread_mutex_unlock(&lk);
break;
}
ex-=2;
pthread_mutex_unlock(&lk);
}
return 0;
}
int main(void)
{
signal(SIGSEGV,sighandler);
ex=100;
pthread_t pth[2];
pthread_mutex_init(&lk,NULL);
pthread_create(&pth[0],NULL,func1,NULL);
pthread_create(&pth[1],NULL,func2,NULL);
pthread_join(pth[0],NULL);
pthread_join(pth[1],NULL);
return 0;
}
I tried to create simpler version of what i would like to know.. There would definitely be access violation in func1 (*p=0) but I would like the func2 to run unhindered while notifying the user of access violation through some kind of log or through controller thread.
Thank You

intermixing c++ exception handling and SEH (windows)

I have a function in which I call getaddrinfo() to get an sockaddr* which targets memory is allocated by the system.
As many may know, you need to call freeaddrinfo() to free the memory allocated by getaddrinfo().
Now, in my function, there are a few places, where I may throw an exception, because some function failed.
My first solution was to incorporate the freeaddrinfo() into every if-block.
But that did look ugly for me, because I would have had to call it anyways before my function returns, so I came up with SEH`s try-finally...
But the problem I encountered is, that it is not allowed to code the throw-statements into the __try-block
Then, I read on the msdn and tried to swap the throw-statements into the helper function called from within the __try-block... and voila, the compiler didn´t moan it anymore...
Why is that? And is this safe? This does not make sense to me :/
Code:
void function()
{
//...
addrinfo* pFinal;
__try
{
getaddrinfo(..., &pFinal);
//if(DoSomething1() == FAILED)
// throw(exception); //error C2712: Cannot use __try in functions that require object unwinding
//but this works
Helper();
//...
}
__finally
{
freeaddrinfo();
}
}
void Helper()
{
throw(Exception);
}
EDIT:
tried the following and it works with throwing an integer, but does not when i use a class as an exception:
class X
{
public:
X(){};
~X(){};
};
void Helper()
{
throw(X());
}
void base()
{
__try
{
std::cout << "entering __try\n";
Helper();
std::cout << "leaving __try\n";
}
__finally
{
std::cout << "in __finally\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
base();
}
catch(int& X)
{
std::cout << "caught a X" << std::endl;
}
std::cin.get();
return 0;
}
Why? :/
You can't mix the two exception types. Under the covers, C++ exceptions use SEH and your SEH exception handler could mess up the exception propogation logic. As a result, the C++ compiler won't allow you to mix them.
PS: Structured Exception Handling is almost always a VERY bad idea. Internally Microsoft has banned the use of SEH except in very limited circumstances. Any component that does use structured exception handling is automatically subject to intense code reviews (we have tools that scan code looking for its use to ensure that no cases are missed).
The problem with SEH is that it's extremely easy to accidentally introduce security vulnerabilities when using SEH.
You could wrap the addrinfo in a class that calls getaddrinfo in the constructor and freeaddrinfo in its destructor.
That way it will always be freed, whether there is an exception thrown or not.
catch(int& X)
{
std::cout << "caught a X" << std::endl;
}
That doesn't catch an X, it catches an int&. Since there is no matching catch block, the exception is uncaught, stack unwinding doesn't occur, and __finally handlers don't run.
You can put catch (...) in your thread entrypoint (which is main() for the primary thread) in order to make sure that stack unwinding occurs, although some exceptions are unrecoverable, that's never true of a C++ 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.