Possible to do the following with Exceptions ?

V

Victor Bazarov

asdf said:
The code I work on has a class called "CException" which gets thrown
whenever there is an exception.

Various other exception class derive from this. The ctor for the
class CException prints out the stack trace using a system function.
So in the code where there is a "throw CException()" the stack trace
gets printed. Even if a derived class gets throwen the stack trace
gets printed because a CException object is created.

Question I have is I want to do the same for exceptions thrown by the
standard c++ library. When I see a std::bad_alloc exception I would
like the stack trace. Is this possible.

It might be possible but it would be implementation- and platform-
specific. There is no standard C++ way of getting "the stack trace"
(there is no such standard term).
I could overried the global operator new and check for exception there
but am wondering if there is a more general mechanism available to do
this for all std exceptions.

No compiler-independent way, AFAIK.

V
 
A

asdf

The code I work on has a class called "CException" which gets thrown
whenever there is an exception.

Various other exception class derive from this. The ctor for the
class CException prints out the stack trace using a system function.
So in the code where there is a "throw CException()" the stack trace
gets printed. Even if a derived class gets throwen the stack trace
gets printed because a CException object is created.

Question I have is I want to do the same for exceptions thrown by the
standard c++ library. When I see a std::bad_alloc exception I would
like the stack trace. Is this possible.

I could overried the global operator new and check for exception there
but am wondering if there is a more general mechanism available to do
this for all std exceptions.

Thanks.
 
Z

Zeppe

asdf said:
The code I work on has a class called "CException" which gets thrown
whenever there is an exception.

Various other exception class derive from this. The ctor for the
class CException prints out the stack trace using a system function.
So in the code where there is a "throw CException()" the stack trace
gets printed. Even if a derived class gets throwen the stack trace
gets printed because a CException object is created.

Question I have is I want to do the same for exceptions thrown by the
standard c++ library. When I see a std::bad_alloc exception I would
like the stack trace. Is this possible.

I could overried the global operator new and check for exception there
but am wondering if there is a more general mechanism available to do
this for all std exceptions.

for the "new" problem, check out "set_new_handler" in the header "new".

Regards,

Zeppe
 
Z

Zeppe

asdf said:
The code I work on has a class called "CException" which gets thrown
whenever there is an exception.

Various other exception class derive from this. The ctor for the
class CException prints out the stack trace using a system function.
So in the code where there is a "throw CException()" the stack trace
gets printed. Even if a derived class gets throwen the stack trace
gets printed because a CException object is created.

Question I have is I want to do the same for exceptions thrown by the
standard c++ library. When I see a std::bad_alloc exception I would
like the stack trace. Is this possible.

I could overried the global operator new and check for exception there
but am wondering if there is a more general mechanism available to do
this for all std exceptions.


for the "new" problem, check out "set_new_handler" in the header "new".

Regards,

Zeppe
 
C

Craig Scott

The code I work on has a class called "CException" which gets thrown
whenever there is an exception.

Various other exception class derive from this. The ctor for the
class CException prints out the stack trace using a system function.
So in the code where there is a "throw CException()" the stack trace
gets printed. Even if a derived class gets throwen the stack trace
gets printed because a CException object is created.

Question I have is I want to do the same for exceptions thrown by the
standard c++ library. When I see a std::bad_alloc exception I would
like the stack trace. Is this possible.

I could overried the global operator new and check for exception there
but am wondering if there is a more general mechanism available to do
this for all std exceptions.

I don't believe that overriding new is a robust solution. When an
exception is thrown, the object that is thrown is not required to be
allocated by new, and indeed rarely is. Rather, a temporary object is
normally created. Item 15.1/3 of the standard says this: "....the
operand of throw is treated exactly as a function argument in a call
(5.2.2) or the operand of a return statement.". The mechanism is
essentially that when the exception is thrown, the (temporary)
exception object is created and when the exception handler finishes
the object is destroyed. The standard says nothing about this object
having to be dynamically allocated using new or destroyed using
delete. Points 15.1/4-6 talk about copying of temporaries, but I don't
believe they require new or delete either.
 
L

Lance Diduck

The code I work on has a class called "CException" which gets thrown
whenever there is an exception.

Various other exception class derive from this. The ctor for the
class CException prints out the stack trace using a system function.
So in the code where there is a "throw CException()" the stack trace
gets printed. Even if a derived class gets throwen the stack trace
gets printed because a CException object is created.

Question I have is I want to do the same for exceptions thrown by the
standard c++ library. When I see a std::bad_alloc exception I would
like the stack trace. Is this possible.

I could overried the global operator new and check for exception there
but am wondering if there is a more general mechanism available to do
this for all std exceptions.
First we should state that stack tracing when an exception is thrown
(a la Java) is not a feature of the C++ language. You are undoubtedly
working in Windows, where they use some hooks into the OS to do this
with certain libraries.
It is possible. CException is in the MFC library. A blunt way would be
to take a version of a std library, change std::exception to inherit
from MFC CException, get all this to compile and link, and then use
this as your default standard library.
And believe it or not, I have seen people do things quite similar to
this, with the expected disasterous results.
A better approach is to take a copy of a std library, and rework the
exception implementation to use the same machinery that MFC uses. You
can read about the details here
http://www.codeproject.com/cpp/exceptionhandler.asp
Then make this your default std library,
This is a better approach, but a lot of work.
An even better approach would be to install a "checked implementation"
of the std library. The latest version of Visual Studio come with this
prepackaged. This integrates with the debugger, and in debug mode you
will get tool far better than simple stack trace printouts.

Yet an even better approach would be to code in a way that does not
rely on stack traces, terminating assertions, or tracing of any kind
(like step debugging) to debug. This approach is often called
"Correct by Construction." and "transacted programming." In this
approach, you place exceptions as a sort of "circuit breaker" for a
requested system state change, and then do quite a bit of static
analysis on the program, and numerous full coverage tests, to make
sure that these circuit breakers don't trip. However, this approach
takes quite some time to master, and normally only found in large
distributed systems, where "tracing the flow" is impossible.
 
J

John

{ Edits: quoted clc++m banner removed. -mod }

First we should state that stack tracing when an exception is thrown
(a la Java) is not a feature of the C++ language. You are undoubtedly
working in Windows, where they use some hooks into the OS to do this
with certain libraries.

Actually I'm working on linux.
It is possible. CException is in the MFC library. A blunt way would be
to take a version of a std library, change std::exception to inherit
from MFC CException, get all this to compile and link, and then use
this as your default standard library.

CException is a code that someone in our software group wrote.
In the ctor for CException the stack is printed out.
And believe it or not, I have seen people do things quite similar to
this, with the expected disasterous results.
A better approach is to take a copy of a std library, and rework the
exception implementation to use the same machinery that MFC uses. You
can read about the details herehttp://www.codeproject.com/cpp/exceptionhandler.asp
Then make this your default std library,
This is a better approach, but a lot of work.

I could take the std library and derive the standards base class
from CException. I was wondering if this is a good way.
An even better approach would be to install a "checked implementation"
of the std library. The latest version of Visual Studio come with this
prepackaged. This integrates with the debugger, and in debug mode you
will get tool far better than simple stack trace printouts.

Yet an even better approach would be to code in a way that does not
rely on stack traces, terminating assertions, or tracing of any kind
(like step debugging) to debug. This approach is often called
"Correct by Construction." and "transacted programming." In this
approach, you place exceptions as a sort of "circuit breaker" for a
requested system state change, and then do quite a bit of static
analysis on the program, and numerous full coverage tests, to make
sure that these circuit breakers don't trip. However, this approach
takes quite some time to master, and normally only found in large
distributed systems, where "tracing the flow" is impossible.

This sounds like something that might be worth looking into.
 
J

James Kanze

Actually I'm working on linux.

If you're using g++, there are two functions available as an
extension which might interest you: __builtin_return_address and
__builtin_frame_address, see section 5.41 of the g++ manual.
And while I know that it is formally off-topic here, I'd be
interested in the names of the functions in Windows which allow
getting such information. (I've got code which hacks it, in a
very non-portable fashion, but if there is an official solution,
I'd far prefer it.)

Also, the GNU binutils package (generally installed by default
under Linux, but it can be compiled to work with most systems)
has a command addr2line, which can be useful in evaluating the
hex addresses the other techniques will give you.
CException is a code that someone in our software group wrote.
In the ctor for CException the stack is printed out.

Actually, I thought that the C prefix meant that the code came
from one of the Microsoft libraries. At least, MFC seems to use
it rather widely. In which case, it may use tricks that aren't
available to common mortals.
I could take the std library and derive the standards base class
from CException. I was wondering if this is a good way.

Modifying the standard library is definitly NOT a good solution.
Think of the code in the standard library which already uses
std::exception---unless you can recompile this, changing
std::exception is almost sure to result in some sort of wierd
behavior.
This sounds like something that might be worth looking into.

Yes. My usual solution is to use something like:

throw Error( MSG() << ... ) ;

My class Error takes an ErrorMessage as an argument (which it
converts to a string, and logs it; the current version doesn't
add a stack walkback, because I've never found any use for it,
but it wouldn't be hard to add. (MSG() is a macro which ensures
automatic insertion of __FILE__ and __LINE__.) If ErrorMessage
converted implicitly to an std::string, it should be possible to
use it directly in something like std::runtime_error.

In general, however, I've very sceptical about adding things
like stack walkback here---even __FILE__ and __LINE__ are
pushing it. If you need a stack walkback, what you probably
want is an abort, and not an exception.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top