Application Shutdown and Windows Error Reporting - windows-error-reporting

We're attempting to update our application in order to submit it for Vista certification. Part of the requirements are to handle only known exceptions and have Windows Error Reporting deal with all unhandled exceptions.
We have a global exception handler in our application (subscribed to the Application.ThreadException event) and in there, we perform certain processing for known exceptions, but if an exception is unknown we wish to throw it out for the app to terminate and WER to handle.
We cannot see a way of doing this and maintaining the call stack if we re-throw then the call stack is recreated.
We've looked at terminating via Environment.FailFast() but we don't believe that that gives the exception information we'd require.
Are we missing something obvious?

Why not just throw a new exception and set the InnerException property to be the unhandled one? The default StackTrace property will concatenate both traces together.
Bear in mind that if you're debugging from a memory dump that you've retrieved from WinQual then it'll be a native exception that's trapped anyway. It's almost always possible to walk back up the native stack and retrieve the managed exception and if you have symbols available it's usually easy to find out what went wrong. The stack trace of the managed exception will be redundant in this situation anyway.

Yes but we're within the Application.ThreadException global handler, not a catch block so we can't just call throw, we'd have to throw e.Exception.

Yea, as Marc states, just use THROW and the original exception will be re-thrown with the stack trace information preserved.
A THROW E will start the whole exception stack over again with the original stack information lost. Typically this is not what you want.
Alternative you can throw a new exception and add the original exception as an inner exception. Then your new exception could add additional bits of information.

Related

Is there a better way to see which function caused a exception other than using catch

I'm having problems with locating the address from which a error occurred, my whole code is running inside of a "try" statement and sadly whenever something is wrong I need to find the error using the old try and fail method by deleting parts of my code. Is there a better way to do it?
My current code:
try
{
do
{
if (somefunction)
if (somefunction2)
if (somefunction3)
if (somefunction4)
}
while (false);
}
catch (...)
{
// todo: somehow get the address where the error occurred
Logger::Log("Exception\n");
}
A simple solution to find out where an exception comes from is to use a unique message within each function. Catch the exception object and print the message. Or perhaps use even a different type of exception which will allow you to efficiently handle each case differently if that's what you want to do.
As for getting an "address", the trace of function calls that lead to the current point of execution is called a stacktrace (or backtrace). The stacktrace would contain information such as addresses. Theres no standard way to get a stacktrace yet, although it has been proposed for C++23.
However, once you've caught the exception, the stack will have been "unwound" such that you can't know where the exception came from. What you could do, is get the stack trace in the code that may be throwing (each of them since you don't know which one is the thrower) and store the trace in the exception. A central place to do that would be within the constructor of a custom exception type. This pattern is common in standard exception handling of modern languages.
Lastly, you don't necessarily need to make any changes to the program, if you instead run the program in a debugger and break on a throw, you can get all the information you can possibly get.

Why wouldn't you declare main() using a function-try-block?

There are a few SO posts about whether or not declaring main() using function-try-block syntax is valid syntax, and the general consensus seems to be that it's perfectly valid. This left me wondering... is there any reason (performance, style, thread synchronization, multithreading) why one wouldn't use this syntax for main() as a general rule to catch any unhandled exceptions anywhere more gracefully?
Obviously, ideally there won't be unhandled exceptions, but they happen and I think it'd be nice to provide something more informative than the OS-specific default handler. For example, in my case, I'd like to provide a support email address to the user so they can report the crash and have my program submit a log to my cloud-based crash log.
For example, in my case, I'd like to provide a support email address to the user
Well, how are you going to do that in a server with no user-facing interface?
Actually, how are you going to do that even in a process with user-facing components, if you have no way to tell in the catch block what state they're in?
And, for those processes where you can't show the user anything useful (or don't have any concept of a "user" in the first place), what would you do in your catch block that would be better than the default terminate?
As for
... more informative than the OS-specific default handler ...
many OS' default behaviour will be to save a complete snapshot of the process execution state, at the point the un-handled exception is thrown, to a file for debugging. As the developer, I can't think of many default behaviours that would be more informative.
Admittedly I'd prefer something more polished as the end user of a desktop app, but that's a pretty small subset of C++ programs.
You can easily convert
int main() try {
// The real code of main
}
catch (...)
{
}
to
int realMain()
{
// The real code of main
}
int main()
{
try
{
return realMain();
}
catch ( ... )
{
}
}
without losing functionality/behavior.
I am going to guess that whether you use the first version or the second version is a matter of coding practices of a team. From a compiler and run time standpoint, I don't see any semantic difference.
If you happened to have a variable that you want to access in your catch block, you would need the curly braces to provide visibility. But even that could be handled with nested try/catch...
why one wouldn't use this syntax for main() as a general rule to catch
any unhandled exceptions anywhere more gracefully?
compatibility with C.
Sometimes there is no way to handle unhandled exceptions more gracefully.
Obviously, ideally there won't be unhandled exceptions, but they
happen and I think it'd be nice to provide something more informative
than the OS-specific default handler. For example, in my case, I'd
like to provide a support email address to the user so they can report
the crash and have my program submit a log to my cloud-based crash
log.
If unexpected exception happens you can not be sure that it is possible to handle it correctly. What are you going to do if there is a network error exception in your example. And trying to send e-mail causes another exception? There can be other errors when you can not be sure that your data is not corrupted and you can not be sure that your program can run correctly after this error. So if you don't know what error happened it is better to allow your program to crash.
You can implement another "watcher" service that checks if process is running and if it has been crashed it can send e-mail to your users with the logs and core dumps.
If you catch the (otherwise) uncaught object, you won't be able to figure out how the execution reached the throw by inspecting the stack trace, because when exception handler is executed, the stack has already been unwound.
If you let the unexpected exception to be uncaught, you may be able to inspect the stack trace in the terminate handler - this is not guaranteed by the standard, but that's not a big deal since there is no standard way to inspect the stack trace either (in C++). You can either use platform specific API within the program, or an external debugger for the inspection.
So for example in your case, the advantage of not catching the exception would be that you can attach a stack trace to the log entry that you intend to submit.
Also, there are cases where an exception can not be handled by a catch block. For example, when you throw from a destructor that is being executed as a result of throwing an exception. So, to handle these "uncatchable" exceptions, you need a terminate handler anyway, so there is little advantage in duplicating the functionality in the case of uncaught exceptions.
As for the syntax that you use to catch the exception, there is no difference. The case where the function try block is different is a constructor, where it allows catching exceptions thrown by sub object constructors.

Get callstack information in CWndApp::ProcessWndProcException(CException* e, const MSG* pMsg)

I have an application that makes extensive use of MFC. Whenever MFC internal asserts fail, my users just get an unhelpful "Encountered Improper Argument" popup. I'd like to add additional logging during these issues to better help track down the actual issue, so I want to make use of CWndApp::ProcessWndProcException. However, I don't know how to get any information out of the exception other than "Encountered Improper Argument" which is just a default message that MFC produces. Is there a way to get call stack information (or exception origin) during this message?
CException does not preserve the call stack information for the catch statement.
You can derive a type from CException that adds additional field for stack trace string and InnerException for the original exception, then wrap the exception-throwing code with a catch handler that rethrow your wrapper exception after stack walking.

Failure to get call stack in a debug build C++

I have a weird situation. My game is definitely being built with debugging information, and I can merrily hit breakpoints and step through code, and look at data. No settings are unusual. I have ruled out multithreading as a problem.
When I have an actual bug, and a legitimate crash, i get no call stack. A typical crash bug will be
First-chance exception at 0x004678da in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
Unhandled exception at 0x774015de in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
And the callstack is just ntdll and some disassembly. I must have changed some option somewhere, but cannot imagine what. Any ideas?
Those errors are indicative of hardware exceptions due to an attempt on your part to access memory that your process cannot read or write. In particular, it looks like you are directly or indirectly attempting to access some element 76 bytes from the address referred to by some pointer, but that pointer is in fact null (thus the access violation reading location 0x0000004c).
Your debug information may not be invalid in any way, you simply may legitimately be in some code inside nt.dll -- for example, if you passed a null pointer to a Windows API function that does not permit them. If you don't have symbols loaded for nt.dll, you won't get a useful call stack.
It's also possible the access violation's coming from a bad pointer you passed that wasn't used until some callback was invoked by the Windows API, which might explain why you don't see your code anywhere in the stack frame.
Enabling break-on-throw in the VS IDE (Debug -> Exceptions, check the boxes for relevant exception types) can help you break earlier when this occurs, but may not help diagnosing the problem if it's legitimately not directly from your code.
You can also use structured exception handling to integrate these exceptions and C++'s exceptions for catching purposes. You may also want to look in to using a symbol server to get the symbols for the Windows DLLs.
Your exception isn't being caught, so it's moving up the call stack all the way to main and terminating your app.
MSDN:
If a matching handler (or ellipsis catch handler) cannot be found for
the current exception, the predefined terminate run-time function is
called.
There's usually an option to allow you to pause debugging when an exception is thrown.
How to: Break When an Exception is Thrown (Visual Studio 2012)
You could also have a catch statement at top level and examine the exception (.what() often gives an description) when you catch it.
Update: You most likely can't catch this exception because it's an Access violation (not a C++ exception, but the pause should still work afaik). If you're on Windows you could use SEH to catch it.

Getting the real C++ exception on x64

If I'm catching a C++ exception of some kind, and in the catch statement throws a new break exception, will I ever be able to retain the original exception if post mortem debugging a crash dump in WinDbg? If so, how?
I've seen the usage of searching for CONTEXT (0001003f) on x86, but it's not valid on x64.
It is possible. You will need to know how to read x64 assembly and find exception record pointer. From there see http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
This will allow you to see the exception object, but at the time the catch statement is executed, stack unwinding has already happened so you will not have the original stack.