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)
Related
I have C++ project which is COM based, in which am accessing the C# assembly. I want to write the code to handle the exception in com project which are thrown by C# assembly.
I tried by placing the try and catch blocks, but exceptions are not been thrown instead the HRESULT value is less than zero. I need the exact message string to display which is thrown by C# API.
Please provide the guidelines for this.
You have two sources of info available. First off, the HRESULT that is returned is not arbitrary, every managed exception has a distinctive HRESULT that helps you identify the kind of Exception object that was thrown.
Next, the CLR implements the IErrorInfo interface. You can QI on the interface pointer you used to call the managed method to get the IErrorInfo interface pointer. IErrorInfo::GetDescription() returns the Exception.Message property value.
That's where it ends, no way to get the holy stack trace.
I'm trying to catch all unexpected terminations in my process.
I've used these functions to catch all the unhandled errors and exceptions that i can think of, but still it's not enough:
SetUnhandledExceptionFilter(OnUnhandledNativeException);
set_terminate(set_terminateHandler);
set_unexpected(set_unexpectedHandler);
_set_purecall_handler(set_purecallHandler);
_set_new_handler(HandleProgramMemoryDepletion);
_set_invalid_parameter_handler(InvalidParameterHandler);
signal(SIGABRT, sigabrt_handler);
signal(SIGINT, sigabrt_handler);
signal(SIGTERM , sigabrt_handler);
These functions catch almost any error in the application.
But, when the application is terminated because of a GDI failure (for example GDI out of resources), non of these functions are called.
Does anyone know how i can catch GDI error events ?
I'm sure there must be some way to overload it and change the callback function.
And, does anyone know of any other weird scenarios where these functions just aren't enough ?
Note:
The exact error that it's not catching is "A required resource was unavailable".
This is caused when you create a lot of GDI objects and don't release them.
The program will crash because there aren't enough resources long before it runs out of memory.
Some of the functions you listed (e.g. SetUnhandledExceptionFilter) set the handlers for the current thread. Therefore you should call them in each thread.
You can add Vectored Exception Handling to the list (AddVectoredExceptionHandler).
If you're on Visual C++ __try __finally will usually do the trick. Note that this is not a portable solution.
Ok, solved the problem.
It WAS catching the crash.
The problem was that as part of the process of salvaging the data from the crash, it was opening a Form which was supposed to notify the user that an error has occurred.
Of course, we're out of GDI objects, so the Form can't be drawn, so that in itself threw and exception, we had another unhandled exception, and the process really crashed.
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
)
{
}
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.
I have unmanaged C++ calling a managed delegate via the function pointer provided by Marshal::GetFunctionPointerForDelegate. This delegate has the potential to throw an exception. I need to be able to properly handle this exception in my unmanaged C++ to ensure things like pointer cleanup, and potentially rethrow the exception up into more managed code. The call stack is similar to this:
Managed Code -> Unmanaged C++ -> callback to Managed Code via delegate (exception can be thrown here).
Anyone have pointers for properly handling this situation so that the resources in unmanaged code can be cleaned up and a usable exception can be thrown out to the managed code which initiated the whole call stack?
Catching from managed code with
try
{
throw gcnew InvalidOperationException();
}
catch(InvalidOperationException^ e)
{
// Process e
throw;
}
And an
[assembly:RuntimeCompatibility(WrapNonExceptionThrows = true)];
on your assembly catches managed and unmanaged exceptions
Don't even remotely try to make the "unmanaged" code aware of the fact that it will have to deal with .NET.
Return a non-zero value from your callback to signal the presence of an error. Provide a (thread local) global string object describing the error so that you can retrieve a helpful error message for the user.
This may involve wrapping your delegate into another function under the scenes, which will catch all the exceptions and return the error code.
One approach would be to use SEH, and do the cleanup in the exception filter before continuing the exception propagation. But I'm not sure that is overly legal since you would be doing a lot of work in the filter. You also wouldn't know anything about the managed exception being propagated.
An alternative is to wrap the managed delegate with your own managed function that catches the exception and in turn throws an unmanaged exception ... which you can then catch in your unmanaged code.
When the unmanaged code has done its cleanup use another helper managed function to re-throw the original managed exception
Managed code represents exceptions as hardware exceptions, unlike C++. You could use SEH. Remember that you always get the chance to run the exception filter.
http://msdn.microsoft.com/en-us/library/ms680657(v=VS.85).aspx
I was told...{the vector can't show if variables a&b weren't declared in the scope process. After a bit of digging figured out that the loop hole was as follows--- weibull_distribution> unmanaged_code