Solved

implementing uncaught_exception in MSVC++ 6.0

Posted on 2003-11-27
11
1,186 Views
Last Modified: 2012-08-14
Hi!
I've regressed to using VC++ 6.0, now that runtime does not implement uncaught_exception properly
see KB: 242192 - BUG: uncaught_exception() Always Returns False

But I need it!

Is there a place where a genuine implementation exist ?

I'm trying to implement a stack trace for our software.
at the start of every function programmers will instanciate a StackTrace object, when an exception is thrown, the StackTrace object in it's destructor will test uncaught_exception and log info if it finds that it is destroyed as part of an exception.


Danderson
0
Comment
Question by:DAnderson
11 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9833605
Hmm, I can only think of a workaround like

#define st_throw(x) { st.set_throw (); throw(x)}

void foo () {

    StackTrace st;

    // some code, some error condition

    st_throw ( new CThisOrThatException ());
}

and evaluate whether 'set_throw ()' indicated an error state. That's ugly, I know, but really implementing 'uncaught_exception()' seems not really easy to me...

BTW: This issue is said to be fixed with VC++ 7.1
0
 
LVL 1

Author Comment

by:DAnderson
ID: 9833761
Nice try!

won't work for me, I'm stuck with 6.0 because tons of legacy
code of a running system . Cannot recompile everything (some throwing functions are in libraries, no source code) same with stl & MFC.

I thought there could be a way to hook into the exception handling mechanism to set the flag. Microsoft do hook into them as they manage to catch exceptions thrown.

I hate those brain damage compilers!

DAnderson
0
 
LVL 86

Expert Comment

by:jkr
ID: 9833779
>>I thought there could be a way to hook into the exception handling mechanism to set the flag

That's what was my 1st thought, too - however, going through the CRT sources that ship with VC++ yields no clue on how one could do that. 'throw()' isn't a simple function, it is a language construct that makes the compiler generate implementation specific code...
0
 
LVL 1

Author Comment

by:DAnderson
ID: 9834279
Yes, throwing & catching is a language construct, but implemented with some low level functions in the libs

There is:
    CxxFrameHandler
    InternalCxxFrameHandler
    Etc...

I thought that maybe someone would have rewritten them to properly set the uncaught flag.

Danderson
0
 
LVL 86

Expert Comment

by:jkr
ID: 9834661
You are certainly right about that - but, if it was that easy to fix the problem, MS would have done that with a service pack (OK, I am being pessimistic here, but just intercepting the aforementioned functions sounds too easy...)
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 16

Expert Comment

by:_nn_
ID: 9836051
For what it's worth, I recall, for having worked a while on that source code tree, that VirtualDub (http://www.virtualdub.org) includes what seemed (at least, to me) to be a quite powerful exception handling system. The application is able to produce stack traces and disassembly listings when it crashes. The "system" is quite complex, involving special build steps (to convert symbols and maps), relies on APIs like SetUnhandledExceptionFilter (so, it's not really a C++ solution), and if I recall correctly, there's a good deal of assembly. It might be challenging to port that mechanism into another application framework, but I'm confident that the study of that source code is worth the time. Maybe not quite what you're looking for, but I thought I'd mention it in case of.
0
 
LVL 1

Author Comment

by:DAnderson
ID: 9846182
I've found a way, now maybe I'm missing something.
so if someone think it it not appropriate let me know

In my stack trace constructor, I register the stack frame (ebp) of the calling function
in the destructor I check if the stack frame of the calling function is the same as the one in the constructor.

if they are the same, it means normal unwinding
if not it means exception unwinding so it is time to log!

What do you think ?

DAnderson
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 9846312
>>if they are the same, it means normal unwinding
>>if not it means exception unwinding so it is time to log!

Hmm, if the exception occurs inside the function, the frame pointer will be the same, regardless of onwinding or not...
0
 
LVL 1

Author Comment

by:DAnderson
ID: 9846718
> Hmm, if the exception occurs inside the function, the frame pointer will be the same,
> regardless of onwinding or not...

Nope!
the handling is not done at the throw point, but within some runtime function
so the stack is different when the destructor is called.

here is pseudo code of thow:

throw(...)
{
   ThrowingStackFrame = GetTrhowingStackFrame();
   HandlingStackFrame = FindHandlingStackFrame();
    ListOfObjectToDestroy = buildListOfObjectToDestroy(ThrowingStackFrame, HandlingStackFrame);
   For Each Object call destructor;    // HERE STACK of thow function!!!!
   SetupStackFrame(HandlingStackFrame);
   return;
}


Danderson
0
 
LVL 1

Author Comment

by:DAnderson
ID: 9851473
jkr, you are right, and I was wrong
ebp is the same, but really I was relying on esp. But I found a problem and sometime esp change within a function: I had forgotten _alloca and other tricks compiler is allowed to play with registers

In debug mode the code for functionning properly, but in release mode with optimised for speed few functions fail

So I cannot reliably find out if I am within an exception context. Bummer.

I guess I'll have to push to upgrade to latest version of  microsoft C++.

Thanks you all for your time

Danderson
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10286197
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: jkr {http:#9846312}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now