From: RB on
Would appreciate input on the following:

Prelude, (keep in mine I understand that for MFC I need to use or
at least wrap all exception handling in a MFC derivation, and use
new (not Referenced& or copies). However in an effort to learn such
a diverse subject as exceptions I have need of input on the following)

" If " I have understood all that I have read on exceptions, then with
Visual C++5 on, compiling with /GX or /EHs, and enables the compiler's
synchronous exception model for C++ exception handling (/GX for mfc apps).
And that this would not (if you did not compile with no optimizations, or
with an asynchronous switch /EHa) catch win32 SE's if you used the catch(...)
and would only catch exceptions (not previously handled with catch(X* Y)
resulting from a C++ throw statement.
And with VC 2005 and after, handles this further and you will only catch(..)
exceptions resulting from a c++ throw. (?)


Ok, assuming that I did not miss the whole idea above, and we are moving
on, my question is:
Do I (or when would I ) need a catch(...) in the first place. In other words
it is only going to catch something I have not already taken care of in a
previous catch(CBaseOrDerivedException* Whatever).
So I am wondering...the only thing that catch(...) could do for me is give
me a chance to do my best at taking care of deletions and file stuff etc
before I rethrow the unknown exception to the OS, or third party class?
In other words I shouldn't just exit the app on a catch(...) without
rethrowing it should I ?

And exactly what is the way to rethrow an unknown exception that I
have caught with a catch(...) ? If I simply issue a lone "throw" inside the
catching catch(...) it appears the exception process has the previous
exception information stored and will it rethrow it again ?

And I am assuming this process will repeat thru any nested try catch
blocks in my app until it exits back (hopefully) to it's originator's
handler ?
From: RB on
I still want input to previous post, but I've been
fooling around with this little app to see which
catchs are caught and when. But I have one question
on it, was does the dtor get called twice in a row on
the unwind ?

----Entire app code with program output below----
#include <iostream.h>
#include <iomanip>
#include <windows.h>

const DWORD CPP_EXCEPTION = 0xE06D7363;

extern struct EHExceptionRecord* _pCurrentException; //CRT struct

const EXCEPTION_RECORD* GetCurrentExceptionRecord()
{
return (EXCEPTION_RECORD *)_pCurrentException;
}

class ThroObj
{
public:
unsigned long ObjVar;
unsigned long FS_0;

ThroObj() : ObjVar(0xAAAAAAAA)
{ cout << dec << "In ThrowObj ctor\n"; }
~ThroObj()
{ cout << dec << "In ThrowObj dtor\n"; }

void ObjFunc()
{
cout << dec << "In ObjFunc\n";
ObjVar = 0xBBBBBBBB;
}

};

void GlobalFunc()
{
try
{
// int Foo, Bar = 0; // Not using on this compile
// Foo = 1 / Bar;
cout << dec << "In 2nd -try block- (in GlobalFunc) fixing to throw ThrowObj\n";
throw ThroObj();
}
catch(...)
{
const EXCEPTION_RECORD* pr = GetCurrentExceptionRecord();
if (pr->ExceptionCode == CPP_EXCEPTION)
{
cout << dec << "In catch(...), and SEH Win32 Exception with code "
<< hex << pr->ExceptionCode << dec << "\noccured at addr "
<< hex << pr->ExceptionAddress << "\n"
<< dec << "fixing to re- throw ThroObj again\n";
throw ThroObj();
}
else if (pr->ExceptionCode != CPP_EXCEPTION)
{
cout << "In catch(...), and SEH Win32 Exception with code " << hex
<< pr->ExceptionCode << dec << "\noccured at addr "
<< hex << pr->ExceptionAddress << "\n"
<< dec << "fixing to re- throw ThroObj again\n";
throw ThroObj();
}
}
}

void main(void)
{

try
{ cout << "In 1st -try block- calling GlobalFunc) \n";
GlobalFunc();
}
catch( ThroObj E )
{
const EXCEPTION_RECORD* pr = GetCurrentExceptionRecord();
if (pr->ExceptionCode == CPP_EXCEPTION)
{
cout << dec << "In outer Catch(ThrowObj E)\n"
<< dec << "Exception code "
<< hex << pr->ExceptionCode << dec << "\noccured at addr "
<< hex << pr->ExceptionAddress << "\n";
}
else if (pr->ExceptionCode != CPP_EXCEPTION)
{
cout << dec << "In outer Catch(ThrowObj E)\n"
<< dec << "Exception code "
<< hex << pr->ExceptionCode << dec << "\noccured at addr "
<< hex << pr->ExceptionAddress << "\n";
}
E.ObjFunc();
}
}
// on the output I see the same First chance exception I always get on my
// debugger output window. I surmise this is because of the debug compile
// has optimizer off (using VC 6 )
First-chance exception in ES1c.exe (KERNEL32.DLL): 0xE06D7363:
/* program output |
In 1st -try block- calling GlobalFunc) |
In 2nd -try block- (in GlobalFunc) fixing to throw ThrowObj |
In ThrowObj ctor |
In ThrowObj dtor |
In catch(...), and SEH Win32 Exception with code e06d7363 <--+
occured at addr 0x7C812AFB
fixing to re- throw ThroObj again
In ThrowObj ctor
In ThrowObj dtor
In ThrowObj dtor <---------------dtor called twice ??
In outer Catch(ThrowObj E)
Exception code e06d7363
occured at addr 0x7C812AFB
In ObjFunc
In ThrowObj dtor
In ThrowObj dtor
end output */
From: Doug Harrison [MVP] on
On Fri, 2 Jul 2010 13:22:52 -0400, "RB" <NoMail(a)NoSpam> wrote:

>I still want input to previous post, but I've been
>fooling around with this little app to see which
>catchs are caught and when. But I have one question
>on it, was does the dtor get called twice in a row on
>the unwind ?

You didn't instrument the copy constructor. Also, when instrumenting these
functions, it's extremely helpful to print the object addresses, i.e. the
this pointers. Doing this would almost certainly have revealed that objects
were being destroyed for which you have no record of their creation. (The
alternative is a bug in the compiler.)

> if (pr->ExceptionCode == CPP_EXCEPTION)
>...
> else if (pr->ExceptionCode != CPP_EXCEPTION)

I think I've seen something like that in the MFC source code. :)

--
Doug Harrison
Visual C++ MVP
From: RB on

> Doug Harrison wrote
> You didn't instrument the copy constructor. Also, when instrumenting these
> functions, it's extremely helpful to print the object addresses, i.e. the
> this pointers. Doing this would almost certainly have revealed that objects
> were being destroyed for which you have no record of their creation. (The
> alternative is a bug in the compiler.)

Thanks Doug. I will set about fixing that.

>> if (pr->ExceptionCode == CPP_EXCEPTION)
>>...
>> else if (pr->ExceptionCode != CPP_EXCEPTION)
>
> I think I've seen something like that in the MFC source code. :)

It may very well be. However I found only references to it as func args
in searches my CRT SRC, in TRNSCTRL.H . Never found the definition
anywhere. The info on webpage "somewhere" that I found it, listed it as being
part of the CRT. In any case it returns real time values of the
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
UINT_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
That "is" defined in winnt.h .
From: Doug Harrison [MVP] on
On Fri, 2 Jul 2010 14:04:23 -0400, "RB" <NoMail(a)NoSpam> wrote:

>>> if (pr->ExceptionCode == CPP_EXCEPTION)
>>>...
>>> else if (pr->ExceptionCode != CPP_EXCEPTION)
>>
>> I think I've seen something like that in the MFC source code. :)
>
>It may very well be. However I found only references to it as func args
>in searches my CRT SRC, in TRNSCTRL.H . Never found the definition
>anywhere. The info on webpage "somewhere" that I found it, listed it as being
>part of the CRT. In any case it returns real time values of the
>typedef struct _EXCEPTION_RECORD {
> DWORD ExceptionCode;
> DWORD ExceptionFlags;
> struct _EXCEPTION_RECORD *ExceptionRecord;
> PVOID ExceptionAddress;
> DWORD NumberParameters;
> UINT_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
> } EXCEPTION_RECORD;
>That "is" defined in winnt.h .

What I was getting at is the logical redundancy in:

if (x == y)
else if (x != y)

It's similar to what MFC (still!) does in CWinThread::OnIdle:

if (lCount <= 0)
else if (lCount >= 0)

--
Doug Harrison
Visual C++ MVP
 |  Next  |  Last
Pages: 1 2
Prev: Show More / Show Less Dialog
Next: Testing ....