How to debug / mitigate uncatchable exceptions - c#

So, for a project I have to use the notoriously error prone GDAL (http://www.gdal.org/) library written in unmanaged C++ (actually I'm using the C# bindings). The problem is sometimes the library bombs and crashes the vhost32.exe process. There is nothing I can do about that. Empty catch blocks won't do me no good, the AppDomain.CurrentDomain.UnhandledException isn't even raised.
The exception thrown is
Unhandled exception at 0x77B9AA3C (ntdll.dll) in RASTER.exe: 0xC0000374: A heap has been corrupted (parameters: 0x77BAFE38).
So obviously this exception is unrecoverable and Windows shuts down my process. So far so good. Now the problem is, where to I go from here? I don't want the whole process to be killed just because a call to a buggy library fails. What are my options? Spawning a second process and using named pipes for inter-process communication? That would still mean that the other process crashes with that "Windows is checking for a solution to the problem..." popup. Not good. Unfortunately, for the functionality I need there is no alternative to that library.
<gcConcurrent enabled="false" />
<legacyCorruptedStateExceptionsPolicy enabled="true" />
in my App.config doesn't change a thing. Neither does decorating the method that bombs with the [HandleProcessCorruptedStateExceptions] attribute.
Is there anything I can do?

Related

Is there any way to print any extended information on StackOverflowException?

One of my clients reported that the software I develop terminates unexpectedly. In app log, the only text available is Process is terminated due to StackOverflowException. There is no more information which would help me diagnose and fix it.
Is there any way to get the location where the exception was thrown? VS breaks on StackOverflowException, but is there any feasible method of diagnosing it without running the application in the debugger (or looking for it in all methods which contain recursion)?
You cannot normally execute any code after a stack overflow, it's one of the rare uncatchable fatal exceptions, so you cannot simply catch it to log any extended details.
The only way you could work around that is by tracking the exceptions from outside of the code that has a stack overflow. You would need to create a native code application to hosts the CLR. If you do that, you can specify that StackOverflowException is not 100% fatal. This is briefly mentioned on the StackOverflowException MSDN page:
If your app hosts the common language runtime (CLR), it can specify that the CLR should unload the application domain where the stack overflow exception occurs and let the corresponding process continue. For more information, see ICLRPolicyManager Interface.
But even that would still mean that a simple try...catch is not sufficient to actually catch the exception. You would have to make sure that the exception handling is not done from the app domain that has a stack overflow. It might be done from a different app domain, or it might be done from unmanaged code.

VS2013 doesn't seem to attach correctly - a debugger is attached to but not configured to debug this unhandled exception

While coding a console app, I'm using an SAP DLL.
I'm getting the following error when trying to add an SAP object:
A debugger is attached to but not configured to debug this unhandled exception. To debug this exception detach the current debugger.
Code:
SAPbobsCOM.GeneralService oGeneralService = oCmpSrv.GetGeneralService("WEPPAGE");
SAPbobsCOM.GeneralData oGeneralData = (SAPbobsCOM.GeneralData)oGeneralService.GetDataInterface(di.GeneralServiceDataInterfaces.gsGeneralData);
oGeneralData.SetProperty("U_WebId", "1");
try
{
oGeneralService.Add(oGeneralData);
}
catch (Exception e)
{
Logger.WriteLog("Error Add object " + e.Message);
}
Although the code is wrapped with try&catch, the IDE crashes.
After many searches and suggestions around the web, which did not helped, I came across this post and applied the suggested solution and enabled native code debugging under the project properties debug tab.
The result of ticking this option was that instead of letting me debug the unknown error, the exception just "disappeared" and the code runs with no interference.
Questions
Why does the exception disappears and not debugged?
Is it possible to have a different workaround for this problem since enabling the native code debugging is slowing down the app by 10x and not a real solution this problem.
Although the code is wrapped with try&catch, the IDE crashes
No, the WER dialog shows that it is your program that crashed, not the IDE. Not your code, OBServerDLL is a SAP component. And given the nature of the crash, using try/catch is not going to be able to catch this exception, it occurs on a worker thread inside the SAP code.
Do keep in mind that the crash reason is very nasty, exception code c0000005 is the equivalent of an AccessViolationException. The usual reason for it is memory corruption. Never catch an exception like that, your program cannot meaningfully continue operating.
Why does the exception disappears and not debugged?
This is certainly not supposed to happen, very unhealthy. AVEs do tend to be rather random, memory corruption does not guarantee a crash. Keep in mind that when it does occur while you are debugging then you still can't find out anything about the reason, you don't have the source code for the OBServerDLL.
enabling the native code debugging is slowing down the app by 10x
That's quite unlikely, unless the native code is throwing exceptions at a very high rate. Something you can easily see in the Output window. What it does do is slow-down the startup of your debug session. The debugger will try to find PDBs for all the native executables, it isn't going to find anything at the Microsoft Symbol Server for SAP code. Simplest way to avoid that delay is using Tools > Options > Debugging > Symbols, untick the "Microsoft Symbols Servers" option.
This question at the SAP support forums would be somewhat comparable. Also the best place to find help with a problem like this. Albeit that it is likely you need support from a SAP escalation engineer, he'll need a small repro project and a minidump of the crashed process.

Catch unhandled exceptions from editor

We are using MEF within our WPF application (MVVM) to embedd external editors. At some point in our main view there is a content element where the editor is going to be placed in.
Now we would like to catch any unhandled exception from that editor and then reload the editor. The only thing I have found is to use DispatcherUnhandledException from the Application class. From there I would have to somehow reach the main view editor and tell it to reload the crashed editor.
I was wondering if there is a "lower" level point, where I could catch the exception? Does anyone have some experience with it and could help he out here?
Thanks
So my answer would be: you better don't if you even could. When you get an unhandled exception, your app is no longer in a stable state. Where exactly would you resume to? What if your external editor throws a Corrupted State Exception (e.g. a Win32 SEH exception) like an AccessViolationException or OutOfMemoryException? Your whole app might be in an undetermined state at that point, so further execution might lead to data loss and/or damage. Furthermore, the CLR might not guarantee that your app can continue:
SEH exceptions are a different class from those exceptions raised by
your program. A program might raise an exception because it tried to
pop an item from an empty stack or tried to open a file that didn't
exist. All of these exceptions make sense in the context of your
program's execution. SEH exceptions refer to a context outside of your
program. Unlike program errors, an SEH exception indicates that the
integrity of the runtime's process may have been compromised.
Please read about SEH and CLR exceptions here.
Here is what I'm not suggesting you to do, but rather for your information: you could prevent your app from closing after catching an unhandled exception by updating your app.config file:
<runtime>
<!-- the following setting prevents the host from closing when an unhandled exception is thrown -->
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
But, as Microsoft states, if you ignore exceptions, the application may leak resources and abandon locks.

How to debug code that interacts with low level APIs (like I/O completion ports)?

I wrote a console application that uses Socket's *Async set of methods and it crashes time to time. It doesn't show me where it threw the exception like synchronized code, console just shuts down and I have no idea what have I done wrong.
Is there a way to detect exceptions when it comes to asynchronous operations like this without knowing where to put a try/catch block?
All I need is to know what part of the code makes my application crash.
Edit:
The usual thing with the unhandled exceptions is when you are debugging your code using Visual Studio, it pauses the execution and shows you the line of code that caused the exception (or at least the exception message). But in some situations (e.g. interacting with a low level API like IOCP) your program just crashes and debugging ends with no information about its cause.
What I need is a way to see that particular exception:
"What happened or where (in which method) it happened so my program crashed?"
So I don't ask "What have I done wrong?", I ask "How can I find out what have I done wrong?"
Can I make the execution break at the point where the exception is thrown?
Can I see the call stack after crash to identify the method that caused it?
Could you provide any advice to avoid these kind of situations?
Click Debug-menu -> Exceptions. Make sure Common Language Runtime Exceptions are thrown. Sometimes the IDE unchecks this option. I don't know why, but it's annoying.
Enable System.Net logging to see whats happening underneath

application level global exception handler didn't get hit

My .net application has a global exception handler by subscribing to AppDomain.Current.Domain UnhandledException event. On a few occassions i have seen that my application crashes but this global exception handler never gets hit. Not sure if its help but application is doing some COM interop.
My understanding is that as long as I don't have any local catch blocks swallowing the exception, this global exception handler should always be hit. Any ideas on what I might be missing causing this handler never been invoked?
Is this the cause of your problem?
AppDomain.CurrentDomain.UnhandledException not firing without debugging
The CLR is not all-powerful to catch every exception that unmanaged code can cause. Typically an AccessViolationException btw. It can only catch them when the unmanaged code is called from managed code. The scenario that's not supported is the unmanaged code spinning up its own thread and this thread causing a crash. Not terribly unlikely when you work with a COM component.
Since .NET 4.0, a Fatal Execution Engine exception no longer causes the UnhandledException event to fire. The exception was deemed too nasty to allow any more managed code to run. It is. And traditionally, a StackOverflowException causes an immediate abort.
You can diagnose this somewhat from the ExitCode of the process. It contains the exception code of the exception that terminated the process. 0x8013yyyy is an exception caused by managed code. 0xc0000005 is an access violation. Etcetera. You can use adplus, available from the Debugging Tools For Windows download to capture a minidump of the process. Since this is likely to be caused by the COM component, working with the vendor is likely to be important to get this resolved.
Since you are doing COM interop I do strongly suspect that some unmanaged code was running in another thread which did cause an unhandled exception. This will lead to application exit without a call to your unhandled exception handler.
Besides this with .NET 4.0 the policy did get stronger when the application is shut down without further notice.
Under the following conditions your application is shut down without further notice (Environmnt.FailFast).
Pre .NET 4:
StackOverFlowException
.NET 4:
StackoverFlowException
AccessViolationException
You can override the behaviour in .NET 4 by decorating a method with the HandleProcessCorruptedStateExceptionsAttribute or you can add the legacyCorruptedStateExceptionsPolicy tag to your App.config.
If your problem is an uncatched exception in unmanaged code you can either run your application under a debugger or you let it crash und collect a memory dump for post mortem debugging. Debugging crash dumps is usualy done with WindDbg.
After you have downloaded Windbg you have adplus (a vbs script located under Programm Files\Debugging Tools for Windows) which you can attach to your running process to trigger a crash dump when the process terminates due to an exception.
adplus -crash -p yourprocessid
Then you have a much better chance to find out what was going on when your process did terminate. Windows can also be configured to take a crash dump for you via DrWatson on older Windows Versions (Windows Error Reporting)
Crash Dump Generation
Hard core programmers will insist to create their own dump generation tool which basically uses the AEDebug registry key. When this key has a value which points to an existing executable it will be called when an application crashes which can e.g. show the Visual Studio Debugger Chooser Dialog or it can trigger the dump generation for your process.
Suspend Threads
An often overlooked thing is when you create a crash dump with an external tool (it is better to rely on external tools since you do not know how bad your process is corrupted and if it is out memory you are already in a bad situation) that you should suspend all threads from the crashed process before you take the dump.
When you take a big full memory dump it can take several minutes depending on the allocated memory of the faulted process. During this time the application threads can continue to wreak havoc on your application state leaving you with a dump which contains an inconsistent process state which did change during dump generation.
This would happen if your handler throws an exception.
It would also happen if you call Environment.FailFast or if you Abort the UI thread.

Categories

Resources