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

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.

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.

Is it OK to store information regarding an error in an Exception object?

I've been reading about exceptions in C++, the pros and cons, and I've yet to encounter anyone mention the two things I really like about them: They allow me to extend the definition of an error (to something that is more than just an error message as a string), and, they allow me to define a contract between the exception handler and the thrower:
"If I'm going to handle this particular type of error, I'm going to
need this, this and that from you."
I've not seen this mentioned in any of the articles, forums and blog posts, as a pro or a con. And that has made me suspect that my mindset on exceptions and how they should be used may be wrong.
To clarify, here's an example of my usage of exceptions:
A program communicates with a USB device (it sends commands to the device and expects a certain response from it). This USB device can sometimes behave in an unexpected way when responding to a command. In this case, the program will throw an UnexpectedResponseFromDevice exception. The handler for this exception needs more than just an error message in order to do its job. For example, it may need to know of the command that we were sending to the device when the error occurred, and/or the state the device was in. I use the definition of my UnexpectedResponseFromDevice class to explicitly set out what is required to handle the exception. See below for a rough idea.
class UnexpectedResponseFromDevice : public std::exception
{
private:
Command command;
DeviceState deviceState;
std::string msg;
public:
UnexpectedResponseFromDevice(std::string msg, Command command, DeviceState deviceState, ...)
Command getCommand();
DeviceState getDeviceState();
};
This is what I meant by "define a contract between the exception handler and the thrower". In order to throw the exception, these things (in this case a Command, a DeviceState and a message) need to be provided.
Is this an acceptable use case for exceptions? Is it OK for me to store this other information, that is required for the handling of the exception, in the exception object? Is it acceptable but a bad idea? If so, please explain why.
Is this an acceptable use case for exceptions? Is it OK for me to store this other information, that is required for the handling of the exception, in the exception object?
Yes, that's how the exceptions in the standard library do too. One example is std::system_error that derives from std::runtime_error but adds a std::error_code member to carry extra information. One that adds a lot more is std::filesystem::filesystem_error that adds two std::filesystem::path objects.
Is it acceptable but a bad idea? If so, please explain why.
It's only a bad idea if you risk throwing another exception (like a std::bad_alloc) while throwing your exception - or if you use exceptions as something else than exceptions, like choosing between common branches in your program flow. Throwing should preferably be a rare event.
If your have all the info you need in a std::string, or even in something like a std::stack<std::string>>, member variable in the object that is a about to throw you can probably std::move that member object into the exception object to minimize the risk - if you don't need that data anymore in the object that is throwing that is.
I don't know how big your std::string, Command and DeviceState objects are, but you may not want to construct the exception object by taking the parameters by value. Try to make construction noexcept. The getters should also probably return by const&. That's not as critical - but making them so minimizes the risk of an exception in your exception handler.
Yes, a parameter is handed over. By means of it information is made available.
catch(const exception& e) { e....; }

SEHException while in paint() - .NET handling is ruining call stack

I have error handling code that is designed to catch unnhandled exceptions, and then create a dump.
Now, i've encountered a few situations where this doesn't work well in the transition between Native and managed code.
For example if in a Paint() event I call some native code, and that native code throws an exception.
The message loop dispatcher will catch the native exception, and then rethrow a .NET SEHException.
Same thing happens sometimes with DLLS that host COM objects.
The problem with this is that because of the stack-roll back and the way it catches and creates an SEHException from the native exception, the actual Native call stack is destroyed.
Can i get the native call stack somehow, using the SEHException ? (note that the call stack in the SEHException is the CLR call stack).
Or can i set the application so it will save the call stack somehow ?
Try !dumpheap -type SEHException . Use the address of SEHException to print !pe address of exception . You will get the callstack
What happens is that .Net called Paint() when it needed to paint a window.
Apparently .Net made this very safe and added extra precautions and error handling.
Now my Paint() event called a C++/CLI wrapper dll that called a native C++ dll. The native C++ exception raised an Access Violation exception.
Now the .Net caught that exception, and wrapped it up as a managed SEHException object, and I've lost all the call stack from the actual error point.
Solution:
We need to catch the exception before the .Net exception handling.
The usual exception handling flow can be found on the net, but this sites gives a good example of the actual flow: Exception handlers
It seems that the .Net catches the exceptions and wraps them before the SetUnhandledExceptionFilter handler is called.
So, I've added a first chance exception handler with AddVectoredExceptionHandler and checked for fatal exceptions by checking the errorcode.
//SEH exceptions have code 0xC0000xxxx
#define SEH_TYPE (DWORD)0xC0000000L
//mask the last byte
#define SEH_MASK (DWORD)0xFF000000L
LONG WINAPI CheckForSEHException( struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter)
{
if ((lpTopLevelExceptionFilter->ExceptionRecord->ExceptionCode & SEH_MASK) == SEH_TYPE) //mask and check the last bits if it's an SEH exception
{
//handle exception here (create a dump or something)
return EXCEPTION_EXECUTE_HANDLER;
}
return EXCEPTION_CONTINUE_SEARCH;
}
The exception codes can be found in WinBase.h, you can follow the definitions to the actual error codes. (ie. look for EXCEPTION_ACCESS_VIOLATION)

Convert std::exception to EXCEPTION_POINTERS

I may be completely misunderstanding how to use the Google Breakpad API, and am open to comments / suggestions / rude remarks if that is the case. I am trying to call the following C++ function:
bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);
I have a reference to a std::exception:
try {
return QApplication::notify(receiver, event);
} catch (std::exception &ex) {
eh_.WriteMinidumpForException(?????);
// ... do some more stuff and ultimately kill this process
}
(eh_ is a google_breakpad::ExceptionHandler.)
What do I put in the ?????
Background: The reason this is necessary (I think) is that Qt will not support an exception thrown in an event handler. It will not propagate correctly, and thus the minidump that Breakpad produces is completely useless because the actual context of the exception has been lost. Instead, you must catch all exceptions and handle them in the override of QApplication::notify(), which is what I am trying to do. In the case of an exception, I want to immediately write my minidump for that exception (which is sounds like WriteMinidumpForException will do) and then notify the user and quit the application. But I am not sure what to pass as the EXCEPTION_POINTERS* parameter.
In the MSVC compiler, C++ exceptions piggy-back onto the native Windows exception plumbing (SEH, Structured Exception Handling). There's a pretty big impedance mismatch though, the concept of an exception filter is doesn't have a good match in C++. By the time the catch handler catches an exception, the SEH exception is already handled and the stack unwound. The EXCEPTION_POINTERS info is gonzo. The exception filters actually exist, that's how it filters for the specific type you want to catch, they are however auto-generated by the compiler. No reasonable C++ syntax exists to make them useful.
You need to dip into the compiler support for handling SEH exceptions. Use the __try, __except keywords (__finally is optional) and have your filter catch the exception code for a C++ exception, 0xe04d5343 ('MSC'). You do however lose the ability to catch a specific C++ exception type, that plumbing is buried in the CRT without source. Put a C++ try inside the __try to fix that so your __except only sees exceptions that the C++ code didn't filter.
Using SetUnhandledExceptionFilter() is another way to do this btw, you really should consider it to act as the ultimate backstop of any unhandled exception, independent of the code location. It is the best way to create a minidump of a crashing app. Last but not least, creating a minidump of a crashing app inside the process itself isn't the best approach. There are plenty of odds that this won't work well, the process state can be corrupted pretty badly. One failure mode is having the process heap locked. Not unlikely considering that heap damage is a very common crash reason. Fix that with a "guard process", use a named event to signal it to make a minidump. Your exception filter only needs to set the event, that always works.
Windows SEH and c++ exceptions are not intertwined in any way - the easy way to solve this is to use your own __try __except wrapping e.g. a dereference of a null pointer.
Something like:
__try {
* (int *) 0 = 0;
}
__except
(
eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
)
{
}

Application Shutdown and 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.