Catch C++ exception over VCL exception routine - c++

I would like to handle of all the C++ exceptions with C++ Builder to generate a crash report that could help me to debug applications when they are installed and used at the clients' places.
I tried to use the function SetUnhandledExceptionFilter but it does not work cause the VCL intercepts the exceptions and does not throw them again.
So I tried this, it doesn't work as well:
unsigned int Filter( unsigned int uiExCode, EXCEPTION_POINTERS *pt )
{
// might create the crash dump....
MessageBox( NULL, L"ENFIN", L"", 0 );
return EXCEPTION_CONTINUE_SEARCH;
}
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
Application->Initialize();
Application->MainFormOnTaskBar = true;
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
__except( Filter( GetExceptionCode(), GetExceptionInformation() ) )
{
// Some code to clear
}
return 0;
}
I don't want to use external libs such as EurekaLog or MadExcept.
Is anyone has an idea how to prevent the VCL from catching all of the exception ?
Thanks.

In my opinion, an automated mapping between VCL and STL is a very big deal.
The solution described in Translate C++ Exceptions to VCL Exceptions causes two hierarchies of logic to be managed, so you will have to catch both EOutOfRange and CppStdOutOfRange if you don't know if the called implementation is VCL or STL... And it's also error prone as the frameworks may evolve.
My advice is to catch every "expectable" "foreign" exception very early and translate it into the appropriate exception of the the one exception hierarchy of your choice: Make sure that all exception classes (that will actually "fly" through your application) inherit (mostly indirectly) from one base class.
One important point that you may have forgotten is, as Hans Passant mentioned, to catch not only the application setup exception (as you currently do), but also the runtime exceptions (i.e. all exceptions thrown within the call of the method TApplication::Run). This can only be done by assigning the event Application->OnException - re-read the docs concerning how to do that technically.
My warm suggestion for a reasonable global exception handler is to show and log a message, then terminate the application. Or even better in this order:
log the message
store it to a global buffer
leave Run by calling Application->Terminate
display the message box in main
a modal message box will keep your poisoned program running - and you don't really know what it does.

As far as I know, there's no straightforward way to achieve what you want. Here's an interesting article that provides information on the subject and explores some possible solutions: http://www.audacia-software.de/en/bcb/external-exception-eefface.htm

Related

Trying to catch exception in MFC's CString::Format

I am working with a C++ project (that I was not the author of) that has a lot of MFC string formatting functions. Unfortunately, stuff like %d and %s are very close together (including the location of letters d and s on the keyboard) that one can be transposed with another. So I may at times witness a code line as such:
CString s;
s.Format(L"Value v=%s", 100); //Should've been %d instead
This results in a hard crash of the process, that is very hard to locate & isolate in the final project. So I was thinking to wrap the Format function in my own override and catch the exception & log it before it is thrown as unhandled exception.
So I employed the following construct:
__try
{
//Do the Format function here
}
__except(1)
{
//Log the error, etc.
}
But unfortunately the construct above did not catch the exception from the first code chunk, so I got VS 2008 C++ debugger kick in and show this:
I then tried this:
try
{
//Do the Format function here
}
catch(int e)
{
//Do the logging
}
But that didn't catch it either.
So how can I catch that fault?
PS. And I have a second question. Is there an easy way to override an MFC function, like Format for instance?
MFC throws CException pointers, so you could try this:
try
{
// Do the Format function here
}
catch(CException* e)
{
// Do the logging then free the exception
if (m_bThrowExceptionAgain)
throw; // Do not delete e
else
e->Delete();
}
You have to delete the exception object once you have caught it as shown in the example. Also make sure you have C++ exceptions enabled in your compiler. See http://msdn.microsoft.com/en-us/library/0e5twxsh.aspx for more information.
As others have already said low-level exceptions (like access violations) are not the same as C++ exceptions. They fall under the term Structured Exception Handling and would require other means to catch, at least by default.
It's possible to change compiler settings (at least in Visual Studio) to make it wrap those exceptions into something that C++ try/catch statements can handle, but as I recall that loses the details of what the SEH exception was and where it came from.
One way or another you could probably get exceptions to work well enough to help track down these issues, but there is also another way: Use static code analysis.
While standard C++ compilers don't normally verify format/printf-style calls, there are various tools that will. In fact some recent versions/editions of Visual Studio come with a code analysis tool, although it may not have been available in VS 2008 which you mentioned. So it might be worthwhile for you to do some research and see if you can get a hold of some kind of code analysis tool which could then catch all the CString::Format mistakes during analysis/compile-time rather than run-time.
You can use _set_se_translator() to convert SEH exceptions like access violation to C++ exceptions which you can then catch with except().
Some sample code: http://www.codeproject.com/Articles/422/SEH-and-C-Exceptions-catch-all-in-one

Recoverying from exceptions

In our application (c++) we load 3rd party DLLs using LoadLibrary.
Sometimes these DLLs cause exceptions, such as "Access violation reading location 0x00000000..".
Is it possible to recover from such an exception, for example using try & catch or some other mechanism? in other world, is that possible to create a sandbox within the same process that withstand such events?
Thank you
No. It's not. A DLL has unrestricted access to the process context that calls it. You need to run untrustable DLLs in their own process context.
In Windows, with VisualStudio compiler, may use SEH mechanism.
__try
{
char* ptr = 0;
char val = *ptr;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
std::cout<<"AV"<<std::endl;
}
Use option /EHa.
You could try a different type of exception handler:
__try
{
// Code that might cause an access violation goes here.
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
int code = _exception_code();
}
Beware though, such handlers can't be used in any routine where C++ objects need stack unwinding as the compiler will warn you (irritatingly).
You can try the /EH flag - http://msdn.microsoft.com/en-us/library/1deeycx5%28v=vs.80%29.aspx - in Visual Studio, but access violation exceptions most likely mean you're doing something very wrong. I'd let the program crash and try to solve the exception, rather than catching it.
It is not possible in c++ if, it is not possible throws a crossmodules exceptions anymore in any case you will have a memory corruption in your application so you have to find out what is going wrong in your dll. You can check the reason you cant throw exception from dll here:
http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
The people behind Runtime-Compiled C++ are using a thing called Structured Exception Handling for their DLL crash-handling routines. Dig into their website or ask them if you want some code samples.
According to the MSDN, the /EHa switch enables "C++ exception handling with structured exception handling exceptions". So if you're using the msvc compiler, you might want to try this.

Uncaught exception in a callback from a 3rd party static library

I am compiling my program with a 3rd party library. That library contains an error callback if an error occurs internally. Inside that error callback I am throwing an exception and I have a unit test to verify that when I do something invalid that the exception is thrown. This all works beautifully in Windows, but when I test this in linux (fedora) I am getting an abort from an uncaught exception.
I tried wrapping my call directly with a try-catch block but no luck. ( Also, all my code is running within the google test framework which also normally catches exceptions ). The only thing that seems to catch the exception is if I wrap the throw statement in a try block directly within the error callback.
Does anyone have any idea why this would happen and if there is a way to catch the exception?
When you interface with third-party libraries you usually have to catch all exception on the border between your code and their code:
int yourCallback( params )
{
try {
doStuff( params );
return Okay;
} catch (...) {
return Error;
}
}
The reason is you can't be sure that library is written in C++ or it uses the very same version of C++ runtime as your code uses.
Unless you're completely sure that code can deal with your exceptions you can't propagate exceptions to third-party code. The extreme example is COM where both your code and "other code" can be in whatever language and with whatever runtime and you are not allowed to let exceptions propagate through COM boundary.
Usually you should not throw exceptions "through" code you do not know anything about. It might be C code, which will not even clean up after itself.
How to deal with your concrete problem would require concrete information about the 3rd-party library you are interfacing with. What is that callback there for? To give you a chance to fix stuff? To inform you that an error occurred? Can you cancel whatever operation it is called from?
One way to deal with such a scenario is to store some information somewhere when the callback is called and check for that information when the actual processing finishes from your function that calls into that library.

Get stack trace from uncaught exception?

I realise this will be platform specific: is there any way to get a stack trace from an uncaught C++ exception, but from the point at which the exception is thrown?
I have a Windows Structured Exception Handler to catch access violations, etc. and generate a minidump. But of course that won't get called in the event of termination due to an uncaught C++ exception, and so there is no crash dump.
I'm looking for a Windows solution at the moment (no matter how dirty!), but would like to hear about other platforms if possible.
Thanks.
We implemented MiniDumps for unhandled exceptions in our last title using the information from this site:
http://beefchunk.com/documentation/sys-programming/os-win32/debug/www.debuginfo.com/articles/effminidumps.html
And to catch the unhandled exceptions on windows have a look at:
SetUnhandledExceptionFilter (http://msdn.microsoft.com/en-us/library/ms680634%28VS.85%29.aspx).
As an aisde, we spent a lot of time experimenting with the different levels of minidump until we settled on one. This proved to be of no real use in real world crashes as we had no idea what they would be at the time the minidumps were implemented. It's very application specific, and also crash specific, so my recommendation is to add the minidump handler as early as possible, it will grow with the project and through QA and it will be a life saver at somepoint (and hopefully out in the real world too).
You can use the try-except Statement to "convert" a C++ exception to a structured exception (out of which you can then get a nice stack trace). Consider this:
// Your function to get a backtrace from a CONTEXT
const char *readBacktrace( CONTEXT &ctx );
extern "C"
static DWORD exceptFilter( struct _EXCEPTION_POINTERS* exInf )
{
OutputDebugStringA( readBacktrace( *exInf->ContextRecord ) );
return EXCEPTION_EXECUTE_HANDLER;
}
try {
// your C++ code which might yield exceptions
} catch ( ... ) {
// In case a C++ exception occurs, raise a structured exception and catch it immediately
// so that we get a CONTEXT object which we can use to generate a stack trace.
__try {
RaiseException( 1, 0, 0, NULL );
} __except( exceptFilter( GetExceptionInformation() ) ) {
}
}
This is a little clumsy, but the nice thing is that you can put the __try { } __except() { } part into a general purpose dumpStackTrace() function. You can then yield stack traces from any point in your program, as you like.
Try using set_terminate to install terminate handler. And in it grab stack trace using mini dump funcitons. Maybe it will work.

Finding out the source of an exception in C++ after it is caught?

I'm looking for an answer in MS VC++.
When debugging a large C++ application, which unfortunately has a very extensive usage of C++ exceptions. Sometimes I catch an exception a little later than I actually want.
Example in pseudo code:
FunctionB()
{
...
throw e;
...
}
FunctionA()
{
...
FunctionB()
...
}
try
{
Function A()
}
catch(e)
{
(<--- breakpoint)
...
}
I can catch the exception with a breakpoint when debugging. But I can't trace back if the exception occurred in FunctionA() or FunctionB(), or some other function. (Assuming extensive exception use and a huge version of the above example).
One solution to my problem is to determine and save the call stack in the exception constructor (i.e. before it is caught). But this would require me to derive all exceptions from this base exception class. It would also require a lot of code, and perhaps slow down my program.
Is there an easier way that requires less work? Without having to change my large code base?
Are there better solutions to this problem in other languages?
You pointed to a breakpoint in the code. Since you are in the debugger, you could set a breakpoint on the constructor of the exception class, or set Visual Studio debugger to break on all thrown exceptions (Debug->Exceptions Click on C++ exceptions, select thrown and uncaught options)
If you are just interested in where the exception came from, you could just write a simple macro like
#define throwException(message) \
{ \
std::ostringstream oss; \
oss << __FILE __ << " " << __LINE__ << " " \
<< __FUNC__ << " " << message; \
throw std::exception(oss.str().c_str()); \
}
which will add the file name, line number and function name to the exception text (if the compiler provides the respective macros).
Then throw exceptions using
throwException("An unknown enum value has been passed!");
There's an excellent book written by John Robbins which tackles many difficult debugging questions. The book is called Debugging Applications for Microsoft .NET and Microsoft Windows. Despite the title, the book contains a host of information about debugging native C++ applications.
In this book, there is a lengthy section all about how to get the call stack for exceptions that are thrown. If I remember correctly, some of his advice involves using structured exception handling (SEH) instead of (or in addition to) C++ exceptions. I really cannot recommend the book highly enough.
Put a breakpoint in the exception object constructor. You'll get your breakpoint before the exception is thrown.
There is no way to find out the source of an exception after it's caught, unless you include that information when it is thrown. By the time you catch the exception, the stack is already unwound, and there's no way to reconstruct the stack's previous state.
Your suggestion to include the stack trace in the constructor is your best bet. Yes, it costs time during construction, but you probably shouldn't be throwing exceptions often enough that this is a concern. Making all of your exceptions inherit from a new base may also be more than you need. You could simply have the relevant exceptions inherit (thank you, multiple inheritance), and have a separate catch for those.
You can use the StackTrace64 function to build the trace (I believe there are other ways as well). Check out this article for example code.
Here's how I do it in C++ using GCC libraries:
#include <execinfo.h> // Backtrace
#include <cxxabi.h> // Demangling
vector<Str> backtrace(size_t numskip) {
vector<Str> result;
std::vector<void*> bt(100);
bt.resize(backtrace(&(*bt.begin()), bt.size()));
char **btsyms = backtrace_symbols(&(*bt.begin()), bt.size());
if (btsyms) {
for (size_t i = numskip; i < bt.size(); i++) {
Aiss in(btsyms[i]);
int idx = 0; Astr nt, addr, mangled;
in >> idx >> nt >> addr >> mangled;
if (mangled == "start") break;
int status = 0;
char *demangled = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
Str frame = (status==0) ? Str(demangled, demangled+strlen(demangled)) :
Str(mangled.begin(), mangled.end());
result.push_back(frame);
free(demangled);
}
free(btsyms);
}
return result;
}
Your exception's constructor can simply call this function and store away the stack trace. It takes the param numskip because I like to slice off the exception's constructor from my stack traces.
There's no standard way to do this.
Further, the call stack must typically be recorded at the time of the exception being thrown; once it has been caught the stack has unrolled, so you no longer know what was going on at the point of being thrown.
In VC++ on Win32/Win64, you might get usable-enough results by recording the value from the compiler intrinsic _ReturnAddress() and ensuring that your exception class constructor is __declspec(noinline). In conjunction with the debug symbol library, I think you could probably get the function name (and line number, if your .pdb contains it) that corresponds to the return address using SymGetLineFromAddr64.
In native code you can get a shot at walking the callstack by installing a Vectored Exception handler. VC++ implements C++ exceptions on top of SEH exceptions and a vectored exception handler is given first shot before any frame based handlers. However be really careful, problems introduced by vectored exception handling can be difficult to diagnose.
Also Mike Stall has some warnings about using it in an app that has managed code. Finally, read Matt Pietrek's article and make sure you understand SEH and vectored exception handling before you try this. (Nothing feels quite so bad as tracking down a critical problem to code you added help track down critical problems.)
I believe MSDev allows you to set break points when an exception is thrown.
Alternatively put the break point on the constructor of your exception object.
If you're debugging from the IDE, go to Debug->Exceptions, click Thrown for C++ exceptions.
Other languages? Well, in Java you call e.printStackTrace(); It doesn't get much simpler than that.
In case anyone is interested, a co-worker replied to this question to me via email:
Artem wrote:
There is a flag to MiniDumpWriteDump() that can do better crash dumps that will allow seeing full program state, with all global variables, etc. As for call stacks, I doubt they can be better because of optimizations... unless you turn (maybe some) optimizations off.
Also, I think disabling inline functions and whole program optimization will help quite a lot.
In fact, there are many dump types, maybe you could choose one small enough but still having more info
http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx
Those types won't help with call stack though, they only affect the amount of variables you'll be able to see.
I noticed some of those dump types aren't supported in dbghelp.dll version 5.1 that we use. We could update it to the newest, 6.9 version though, I've just checked the EULA for MS Debugging Tools -- the newest dbghelp.dll is still ok to redistribute.
I use my own exceptions. You can handle them quite simple - also they contain text. I use the format:
throw Exception( "comms::serial::serial( )", "Something failed!" );
Also I have a second exception format:
throw Exception( "comms::serial::serial( )", ::GetLastError( ) );
Which is then converted from a DWORD value to the actual message using FormatMessage. Using the where/what format will show you what happened and in what function.
By now, it has been 11 years since this question was asked and today, we can solve this problem using only standard C++11, i.e. cross-platform and without the need for a debugger or cumbersome logging.
You can trace the call stack that led to an exception
Use std::nested_exception and std::throw_with_nested
This won't give you a stack unwind, but in my opinion the next best thing.
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
It will, however, require that you insert try/catch statements at the functions you wish to trace (i.e. functions without this will not appear in your trace).
You could automate this with macros, reducing the amount of code you have to write/change.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"