I'm trying to write some code to wrap a c++ library that throws unmanaged exceptions.
Just for testing purposes, is it possible to generate an unmanaged exception from c# code without having to create a fake c++ library standin?
The C# Programming Guide states that "In C# you cannot throw non-CLS exceptions". This means you can only throw exceptions deriving from the Exception class, i.e. managed exceptions. You'll have to create a c++ library standin.
Incidentally, the same page also explains how to catch such exceptions. However, this only applies when the c++ code in question is actually throwing an exception - if it's an access violation this will be a Corrupted State Exception which cannot be caught, see here for more.
Related
Currently, there is no way (at least I did not find a way) to catch fatal exceptions (such as Stack Overflow, Segfault, ..) with try-catch block.
I already started issue at .net core repository so for more details you can read there (https://github.com/dotnet/core/issues/4228)
What I'm trying to do is to make the application not crash when there is any segfault/stack overflow/any fatal exception in loaded unmanaged code. what happens now is that .NET CLR kills my application if any fatal error occurs.
Example:
In c# managed code loaded external c++ dll via kernel LoadLibrary function.
Assume the dll is intentionally created for robustness testing therefore when a specific function is called it triggers segfault (e.g. trying to get data from outside of array bounds).
When this error happens this gets caught by .net CLR and immediately kills the calling managed c# code(application).
What I would like is just report that this happens instead of dying silently.
I did some research and found out there is the reasoning behind that which is described in the issue above.
The CLS is more restrictive than the CLR, which would allow you to throw and catch any type of objects (even value types). Why?
Also what would happen if some non CLS-compliant code threw a non Exception derived object while called by a CLS compliant code?
UPDATE
Second question answered by #Marton. Still wonder why.
CLS specifies a minimum set of language features needed by many applications in such a way that if an API uses only those features, it can be consumed by any CLS-compliant language. So naturally it is more restrictive than the CLR. On the other hand, the CLR is deigned to handle manged code from any CLI-compliant language.
An example of a language that allows throwing non-CLS-compliant exceptions (those not derived from System.Exception) is C++/CLI. This language was designed to be a superset of plain C++ which includes the ability to throw exceptions of any type. This could be the only good reason to throw non-CLS exceptions.
Regarding the second question. A non-CLS exception, when thrown, different things happen in different cases:
If CLR 1.X is managing the execution of the code, the exception propagates as is. In languages that only support CLS exceptions (C#), the exception can only be caught by a parameterless catch block. There is no easy way to access the exception and a stack trace will not be recorded.
On CLR 2.0 and later, the CLR internally always wraps the exception into a System.Runtime.CompilerServices.RuntimeWrappedException which maintains a field of type Object that references the original exception. This allows a stack trace to be recorded. When it propagates up the stack:
If the System.Runtime.CompilerServices.RuntimeCompatibilityAttribute attribute was applied on the assembly of the function in which the CLR is looking for a matching catch block and WrapNonExceptionThrows set to true (automatically applied by the Visual C# and Basic compilers), then the exception continues to be wrapped.
Otherwise, if the attribute was not applied or if WrapNonExceptionThrows was set to false, the exception is unwrapped every time a catch block is examined for matching.
Edit
In C#, in the first bullet above and the second case of the second bullet, the only way to catch a non-CLS exception is by using a parameterless catch block.
The why part I cannot answer, but the second part I can:
what would happen if some non CLS-compliant code threw a non Exception
derived object while called by a CLS compliant code?
If you throw a non-Exception-derived object, it will still be caught by CLS-compliant code, since it will be wrapped into a RuntimeWrappedException.
(The source article is worth a read for more details.)
I am using a fingerprint capture device in my c# application, this device has c# wrapper class for a c++ SDK dll.
Sometimes i get a c++ exception message (see image) and then the application close, the problem is that I can't catch this exception and can't keep application running after this exception.
The Question is: How Can I Catch This Exception in C#?
How Can I Catch This Exception in C#?
You cannot. An unmanaged C++ exception cannot be caught by managed code. You need to catch unmanaged exceptions in unmanaged code. You cannot let unmanaged exceptions propagate outside the unmanaged module.
However, the error dialog suggests that you have a more serious problem. One that cannot be dealt with simply by catching an exception. You will need to work out why your program is terminating the runtime in this catastrophic way, and stop that happening. That error dialog suggests that your program is calling abort(), which is terminal.
In other words you need to prevent this error from happening in the first place, rather than attempting to recover from it. This is not an error that you can hope to recover from.
I've got a weird symptom in an application, where try/catches inside the handler for UnhandledExceptions don't work: (that is a breakpoint inside the catch does not get hit, even if the breakpoint inside the try does).
Obviously searching for 'exception unhandled inside UnhandledException' is not working very well for me.
I've tried doing a mini proof-of-concept, and unfortunately that one works.
So while I'm trying to track down the root of the problem, if anyone here has any ideas where to look I'd be greatful.
(We recently changed from XP to Windows7, and .Net 4.5 from 4.0 - I'm pretty certain that previously this worked).
EDIT: Looks like it's provoked by a call down to a (managed) C++ library which is throwing a System.AccessViolationException. Strangely, if I replace the call with a throw new AccessViolationException, it does do what I want...
You wrote, "We recently changed ... .Net 4.5 from 4.0 - I'm pretty certain that previously this worked." but the following seems worth adding, because pretty sure really means not certain :-)
I read somewhere that AccessViolationException cannot occur in managed code, but may be trapped by the runtime for unmanaged code. Maybe the C++ library calls into unmanaged code?
In .NET 4+ the process will terminate after AccessViolationException. Your exception handler will be ignored. This is among a group of exception types considered unrecoverable: Corrupted State Exceptions. In .NET 4+ you will need to customise the app config to override this behaviour.
Be sure that you try to catch System.AccessViolationException and not native Access Violation error.
When you do throw new AccessViolationException it throws System.AccAccessViolationException.
If library that you calls is native it can throw native Access Violation error, but .NET catch block normally can catch only managed exceptions.
try this:
i think we can't handle Unhandeled exception and have to exit application in finally.
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
I'm trying to use code similar to clrdump to create mini dumps in my managed process.
This managed process invokes C++/CLI code which invokes some native C++ static lib code, wherein SEH exceptions may be thrown (e.g. the occasional access violation).
C# WinForms
->
C++/CLI DLL
->
Static C++ Lib
->
ACCESS VIOLATION
Our policy is to produce mini dumps for all SEH exceptions (caught & uncaught) and then translate them to C++ exceptions to be handled by application code. This works for purely native processes just fine; but when the application is a C# application - not so much.
The only way I see to produce dumps from SEH exceptions in a C# process is to not catch them - and then, as unhandled exceptions, use the Application.ThreadException handler to create a mini dump. The alternative is to let the CLR translate the SEH exception into a .Net exception and catch it (e.g. System.AccessViolationException) - but that would mean no dump is created, and information is lost (stack trace information in Exception isn't as rich as the mini dump).
So how can I handle SEH exceptions by both creating a minidump and translating the exception into a .Net exception so that my application may try to recover?
Edit
By "not catching exceptions" I also mean catching and then rethrowing, which does preserve the rich exception information.
Right now I'm considering never supressing System.Exception or anything deriving from System.SystemException. This means AccessViolation (and friends) always cause the program to end and produce a dump, and all other exceptions thrown need to derive from some sub-type (ApplicationException?).
I found that with Vectored Exception Handling I can get a first-chance notification of any SEH exception and use this occasion to produce a mini dump.