From: Joseph M. Newcomer on
I can only answer part of your question.

In VS, there is a way to turn on handling exceptions which intercepts them at the point
where they occur; to enable this, go to Debug >Exceptions.

You might want to consider putting in some exception handlers of your own. I'd looking at
Doug Harrison's article on exceptions at

http://members.cox.net/doug_web/eh.htm

Ultimately, when using exceptions, I found that the only good way to defend is to have
LOTS of try/catch blocks scattered widely. One system I worked in too a year of doing
this before I got every situation covered (and remember: if you write a try, you HAVE to
have a recovery strategy for the catch, or you haven't solved the problem. That's what
takes the time. In many cases, you have to clean up with something like
catch(CException * e)
{
...do local cleanup...
throw;
}

or alternatively
catch(CException * e)
{
... do local cleanup...
e->Delete();
throw new CSomeOtherException(...maybe parameters here...);
}

As I say, expect to spend a LOT of time doing this. The downside of writing bulletproof
software is that it is a LOT of work! Programs that run 24/7 are not at all the same as
little utilities that run once for 2 seconds and exit. I've done both, and making that
24/7 software seriously bulletproof is a major undertaking.

Sometimes you get help from the customers, but in the big picture, having your program log
its failures is one of the critical things. Sprinkling some try/catch blocks around that
say
catch(CException * e)
{
...log exception with __FILE__ and __LINE__ and even _T(__FUNCTION__) when
appropriate, e.g.,
Log(_T("Exception seen in ") _T(__FUNCTION__) _T("[") _T(__FILE__)
_T("(%d)]: ...blah blah"), __LINE__);

throw;
}

is sometimes a good start because these are low-cost to sprinkle around, but ultimately
you have to deal with doing good recovery. The MFC catch-at-message-loop, as you point
out, doesn't really solve the problem.

Note that there are levels of exposure here you might not find acceptable, such as having
file names, line numbers, function names, nature of error, etc. So if you take Log as
being

/* static */ void LoggingSystem::Log(const CString & fmt, ...)
{
var_args args(fmt);
CString s;
s.FormatV(fmt, args);
CString msg = encrypt(s);
OpenLogFile();
WriteLogFile(msg);
CloseLogFile();
}

your Encrypt() function [which should insert 0 bytes into the file, in the ideal case...]
hides information. When the customer sends you the log file, you apply a corresponding
Decrypt() function to the file contents and get back what you need to see.

I will add the fact that CInvalidArgException is not documented to my "errors and
omissions" document, which is small consolation to you, but at least it points out a
problem.
joe




On Tue, 5 Jan 2010 05:36:43 -0800 (PST), Peter Schneider <peter.m.schneider(a)gmx.de> wrote:

>Hello,
>
>in AfxCallWndProc MFC catch exceptions derived from CException (in
>particular CInvalidArgException which is thrown by some MFC functions
>such as CArray::GetAt even though this is undocumented). A message box
>will be shown but then the application will continue to run in a
>potentially corrupt state.
>
>This makes it hard to find the root cause of an unhandled exception,
>particularly when a problem is difficult to reproduce or occurs only
>on customer machines, for example.
>
>I'd prefer a normal crash and a good old crash dump showing the call
>stack at the time the exception was thrown. Is there a way to achieve
>this?
>
>Thanks,
>Peter
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm