Regarding Exception handling
I use try/catch within a function like this,
Code:
void foo()
{
...
try{
...
}
catch(...)
{
}
...
}
I am not able to give a very concrete example since it is too complicated. I just expect to get some clues. Basically there is an exception in the statement within try(I am sure there is one). But to my surprise catch(...) couldn't catch any exception. But the caller of the function foo catches an exception from the statement within the try like the following. I set enabling exception in visual studio and also set option to SH/a.
Code:
void bar()
{
try{
foo();
{
catch(...)
{
}
}
Here an exception is caught. But my understanding is that since try within the function foo is inner try, so an exception should be caught by it instead of try used in the function bar(). Can any guru here give me some clues how it happens? Thanks.
Re: Regarding Exception handling
Quote:
Originally Posted by
LarryChen
I use try/catch within a function like this,
It is very important to tell us what you are attempting to catch and to post complete code so that we know we aren't being misled as to what your code really is doing.
Quote:
I am not able to give a very concrete example since it is too complicated
What is so complicated as providing a full program less than 10 lines long? You throw something, and it isn't caught, so just write a simple program that throws and shows us what doesn't work. Second, if it's so complicated, wouldn't the fact that it is complicated make it possible that your observations are wrong and you're not giving us correct info?
Here are two very simple examples -- please fill in the gaps as to what you are experiencing.
Code:
void foo()
{
try
{
char *p = 0;
*p = 'x';.
}
catch(...)
{
//
}
}
int main()
{
try
{
foo();
}
catch (...)
{
}
}
Code:
void foo()
{
try
{
throw 1;
}
catch( ... )
{
//
}
}
int main()
{
try
{
foo();
}
catch (...)
{
}
}
Two examples -- the first relies on the CRT libraries to do a throw on an access violation. The second guarantees that something is thrown. So out of these two examples, which one fits what you're doing?
Regards,
Paul McKenzie
Re: Regarding Exception handling
What exception are you talking about? If an exception isn't caught, your debugger should give you an unhanded exception error.
Re: Regarding Exception handling
Here is an example which is very close to actual project but there is an importance difference, ie., foo is actually a callback function in the actual project. However end result is also different. In this example, "foo" will be printed out. But "main" will be printed out in the actual project. I wonder why? Thanks.
Code:
#include <iostream>
using namespace std;
class badObj
{
public:
badObj()
{
_x = 0;
}
void bar()
{
_x++;
}
private:
int _x;
};
void foo(badObj* p)
{
try
{
p->bar();
}
catch(...)
{
cout<<"foo"<<endl;
}
}
int main()
{
badObj* pObj = new badObj;
pObj+=10000000;
try{
foo(pObj);
}
catch(...)
{
cout<<"main"<<endl;
}
}
Re: Regarding Exception handling
Quote:
Originally Posted by
LarryChen
Here is an example which is very close to actual project but there is an importance difference, ie., foo is actually a callback function in the actual project.
Your example doesn't guarantee anything will be thrown. Advancing a pointer to an unknown location doesn't guarantee that any exception will be thrown.
The code I posted guarantees that an exception is thrown if SEH is on in the first example. For the second example, the code explicitly throws an int, so regardless if SEH is on or off, an exception is thrown.
Regards,
Paul McKenzie
Re: Regarding Exception handling
Quote:
Originally Posted by
Paul McKenzie
Your example doesn't guarantee anything will be thrown. Advancing a pointer to an unknown location doesn't guarantee that any exception will be thrown.
The code I posted guarantees that an exception is thrown if SEH is on in the first example. For the second example, the code explicitly throws an int, so regardless if SEH is on or off, an exception is thrown.
Regards,
Paul McKenzie
But a data _x will be added 1 in the function bar by calling that pointer. So definitely an access violation exception will be thrown.
Re: Regarding Exception handling
Quote:
Originally Posted by
LarryChen
But a data _x will be added 1 in the function bar by calling that pointer. So definitely an access violation exception will be thrown.
No, it is not definite.
Just because you've picked a random place to move your object doesn't mean that the random place is off-limits to your application. Writing to random places in memory does not guarantee exceptions being thrown. If that were the case, then C++ would be a much easier language to use, as any memory overwite or out-of-bounds access would be automatically detected, and you know that's not the case.
If you want an exception thrown, you write to location 0, as I've done.
Regards,
Paul McKenzie
Re: Regarding Exception handling
Quote:
Originally Posted by
Paul McKenzie
No, it is not definite.
Just because you've picked a random place to move your object doesn't mean that the random place is off-limits to your application. Writing to random places in memory does not guarantee exceptions being thrown. If that were the case, then C++ would be a much easier language to use, as any memory overwite or out-of-bounds access would be automatically detected, and you know that's not the case.
If you want an exception thrown, you write to location 0, as I've done.
Regards,
Paul McKenzie
I see. Do you have any clues why exception caught different way in my project? Is it because call back function is used?
Re: Regarding Exception handling
Paul ,
whats does SEH stands for?
Is it Segment Exception Handling or what?
Re: Regarding Exception handling
Quote:
Originally Posted by
LarryChen
I see. Do you have any clues why exception caught different way in my project? Is it because call back function is used?
A callback was invoked asynchronously from a thread. Hence, if you don't achieve to catch the exception in the callback function itself, it must be caught from thread function that invokes the call. That all looks as if you have problems with your stack or with the memory management of your callback function. For example if you passed a local buffer with your callback function which has gone out-of-scope when the callback function was invoked, it could result in such behavior you reported.
To know better you should change your debug settings regarding the thrown exception (I assume it is access violation) so that the debugger was invoked immediately when the exception was caused and not after it has recognized that it wasn't handled properly. You find this setting below Debug - Exceptions ... - Win32-Exceptions.
Re: Regarding Exception handling
Quote:
Originally Posted by
itsmeandnobodyelse
A callback was invoked asynchronously from a thread. Hence, if you don't achieve to catch the exception in the callback function itself, it must be caught from thread function that invokes the call. That all looks as if you have problems with your stack or with the memory management of your callback function. For example if you passed a local buffer with your callback function which has gone out-of-scope when the callback function was invoked, it could result in such behavior you reported.
To know better you should change your debug settings regarding the thrown exception (I assume it is access violation) so that the debugger was invoked immediately when the exception was caused and not after it has recognized that it wasn't handled properly. You find this setting below Debug - Exceptions ... - Win32-Exceptions.
Actually, what happens is like this. Say I have a callback function A and A calls function B. Function B will throw an access violation exception. But it is very strange that the exception couldn't be caught by B, and it is always caught by A! Basically A passes an invalid pointer to B, then B is trying to use this invalid pointer and then an exception is thrown. But what I don't understand is that why B couldn't catch this exception.
I read a discussion in http://social.msdn.microsoft.com/For...9-5bd7a8338b94. There is a post I am quoting here.
Quote:
If structured exception handling isn't capturing the access violation it is probably because the stack was trashed and thus there was no possible way for the exception hanlding code to find your catch block. If you had simply referenced some memory that was inaccessible (for example, by using a bad pointer) then the __try/__except would have caught the access violation.
I guess it is probably related to my problem. Can anyone here explain what it really means? I am thinking it is possible that in my case, when an access violation exception is thrown, the stack belonging to function B is trashed so that the catch block in B could not be found. Does it make any sense?
Re: Regarding Exception handling
Re: Regarding Exception handling
Quote:
Originally Posted by
S_M_A
Since access violation exception is a hardware exception, so if it is caught by c++ exception handling, that won't be reliable. Am I right? I did find out that if an access violation exception is caught be c++ exception, sometimes it succeed and sometimes it fails. So in order to catch access violation exception RELIABLY, I need to call se_translator to convert a hardware exception to a c++ exception like this,
Code:
try{
int* x = 0;
*x = 1;
}
catch(se_translator::access_violation& ex)
{
...
}
Please share your comments with me. Thanks.
Re: Regarding Exception handling
Quote:
Originally Posted by
LarryChen
So in order to catch access violation exception RELIABLY, I need to call se_translator to convert a hardware exception to a c++ exception like this,
None of this works if something doesn't throw. You can do all the try/catch in the world, if nothing does a throw, you aren't going to catch anything,
The way that try/catch works is simple -- something must throw first. The throw is part and parcel of this whole scheme, and you're leaving out this important step.
If anything, the se_handler gets invoked by the OS, then you're responsible to put together an exception object in your C++ code, and you throw your exception object.
Code:
void your_se_exception_handler( whatever )
{
// create your own exception object derived from std::exception
MySEException se;
//....
throw se;
}
//...
try
{
int *p;
*p = 0;
}
catch( MySEExceptioin& se )
{
}
In general, a catch() only happens when one of these scenarios happens:
1) A C++ function in third-party code explicitly does a throw.
2) A standard C++ library function throws (and only a few scenarios occur where the C++ library explicitly throws, for example operator new on failure, the vector::at() function on failure, failure of dynamic_cast when given a bad reference, etc.)
3) Your code does a throw.
Here is another link -- it basically explains what I've stated.
http://msdn.microsoft.com/en-us/libr...(v=vs.80).aspx
Note that you must do the throw when the exception function handler gets called.
Regards,
Paul McKenzie
Re: Regarding Exception handling
Quote:
Originally Posted by
Paul McKenzie
None of this works if something doesn't throw. You can do all the try/catch in the world, if nothing does a throw, you aren't going to catch anything,
The way that try/catch works is simple -- something must throw first. The
throw is part and parcel of this whole scheme, and you're leaving out this important step.
If anything, the se_handler gets invoked by the OS, then you're responsible to put together an exception object in your C++ code, and you throw your exception object.
Code:
void your_se_exception_handler( whatever )
{
// create your own exception object derived from std::exception
MySEException se;
//....
throw se;
}
//...
try
{
int *p;
*p = 0;
}
catch( MySEExceptioin& se )
{
}
In general, a catch() only happens when one of these scenarios happens:
1) A C++ function in third-party code explicitly does a throw.
2) A standard C++ library function throws (and only a few scenarios occur where the C++ library explicitly throws, for example operator new on failure, the vector::at() function on failure, failure of dynamic_cast when given a bad reference, etc.)
3)
Your code does a throw.
Here is another link -- it basically explains what I've stated.
http://msdn.microsoft.com/en-us/libr...(v=vs.80).aspx
Note that
you must do the throw when the exception function handler gets called.
Regards,
Paul McKenzie
Here is an example from you,
Code:
void foo()
{
try
{
char *p = 0;
*p = 'x';.
}
catch(...)
{
//
}
}
int main()
{
try
{
foo();
}
catch (...)
{
}
}
In the try block of function foo, no throw is thrown. So you think catch never catches any exception? But that doesn't sound like what you meant in your early post. Please point out if it is my misunderstanding. Thanks.