I have tried to use NUnit to test C# code the is already connected to C++ code (without the NUnit the application work perfectly).
In my test I run the main function through AppDomain.CurrentDomain.ExecuteAssembly(..), However when the C# code tries to "communicate" with the C++ it throws an exception and the test crashes. The exception is System.Reflection.TargetInvocationException if anyone has and idea why its happen it will be very very helpful... Thanks, Naama
Your suspicions are correct it is being through during the constructor, the constructor in c# is trying to create an object (it is already wrapped and work perfect when the application is running normally) that is written in c++ and in c++ in the constructor of the object the exception is thrown.
However the application is very complex but if it necessary for clarification I will write a demo application that symbol the real one.
It is likely that an exception is being thrown in your C++ code, in the constructor of the class. Check to make sure you're handling exceptions properly and that you're giving the proper information to the constructor so exceptions aren't thrown.
Related
I have a WinForms application which dynamically loads an assembly generated by MatLab (3rd Party). Currently, I encountered the problem that an error (maybe exception) somewhere in the MatLab code structure, cannot be caught on C# side. And by this, the whole application goes down...
What I tried is:
Try/Catch Block (even with no exception type, as described here: https://stackoverflow.com/a/150675/3809520)
HandleProcessCorruptedStateExceptions attribute, as described here: https://stackoverflow.com/a/10517244/3809520)
Is there anything that I could do more?
Thanks!
Edit:
Application is using .NET 4.5 Framework
Edit2:
Tried Application.ThreadException event together with Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) and AppDomain.UnhandledExceptions event as proposed in comment - both events not triggered.
Edit3:
I will try to nail it down to a minimal example, the questions was intended to be more generic, like: what else can be done on my code side to catch exceptions
NOTE ADDED AFTER SOLUTION: An AccessViolationException was being thrown inside the method called by reflection. This was the reason the TargetInvocationException couldn't be caught.
NOTE: This is OUTSIDE of the IDE. The referenced question is NOT the same.
TL;DR
Can't get a stack trace
Can't get inner exceptions
Can't use debugger (copy protection scheme of a third party library gets in the way)
Any changes to the code prevent the exception from occurring - means I can't add logging to find out where the exception occurrs
How can I get the exception to be caught or get the needed information some other way?
Long description:
I am having a problem with an exception that occurs in a method that gets called by reflection. The exception itself actually occurs in the called method, but since the method is called by reflection, the real exception gets wrapped in a System.Reflection.TargetInvocationException. No problem, just catch it and get the internal exception - except the System.Reflection.TargetInvocationException doesn't get caught. My program crashes, and I get a dump along with an entry in the Windows event log.
The Windows event log doesn't contain the internal exceptions, and neither does the dump.
I can't attach a debugger to the program because then an external library (which is needed to get to the reflection call) won't run - copy protection, don't you know.
If I put a try/catch into the offending method, the exception doesn't occur - which is bad. The cause isn't fixed, it just doesn't happen any more.
The same effect happens if I put logging into the offending method - the exception doesn't occur any more.
I can't use logging, I can't use a debugger, and in the one place where I could catch the exception and log it the exception doesn't get caught.
I'm using Visual Studio 2010 and dotnet 4.0.
To make it clear: The try/catch doesn't work when the program is run outside of Visual Studio, and I can't run it inside of Visual Studio in the debugger because then the program can't reach the point where the exception occurs. This is NOT within the IDE.
Eliminating the reflection isn't an option (I've tried it for just the one case, and the exception goes away.)
The method being called does a lot of stuff, but breaking it down into smaller methods doesn't help - the exception just goes away.
The exception doesn't occur all the time, only when I do a certain sequence of steps - and when it occurs then it is always on the second time through the whole sequence.
In the sequence I am using, the method gets called by two threads almost simultaneously - a particular bunch of data gets entered, which causes a copy of a report and another document to be printed on two separate printers - one report and document to each printer. Since generating the reports and printing the document can take a while, they are done on threads in the background so the user can continue working.
I suspect that the threads are stepping on each others toes (lots of file and database manipulations going on) but without knowing what is really happening I can't fix it.
The code below shows a simplified version of the call by reflection.
Does any one have a suggestion as to what may be causing the System.Reflection.TargetInvocationException to not be caught, or maybe an alternative way to catch the inner exception?
Try
Dim methode As System.Reflection.MethodInfo
methode = GetType(AParticularClass).GetMethod("OneOfManyMethods", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static)
Dim resultobject As Object = methode.Invoke(Nothing, Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static, Nothing, New Object() {SomeBooleanVariable, SomeStringVariable}, Nothing)
result = DirectCast(resultobject, DataSet)
Catch ex As Exception
'Log the error here.
End Try
Found the reason why I couldn't catch the exception:
The actual exception was an AccessViolationException, which can't be caught in dotnet 4.0 without taking special steps (How to handle AccessViolationException.)
To make things more fun, when AccessViolationException gets thrown in a method called by reflection, only a TargetInvocationException gets logged in the Windows event log, and only the TargetInvocationException is available in the dump.
Once I managed to get the real exception, I found that that it was a call to Application.DoEvents() from a non-GUI thread that caused the AccessViolation. DoEvents() can cause enough fun when called on the GUI-Thread (Use of Application.DoEvents()), let alone when called from a background thread.
Once that was fixed, I found that our third party library (the one with the copy protection) doesn't like being called simultaneously in separate instances. Fixing that was a matter of a synclock in the right place.
The code causing all of this fun was at one time all in the GUI-Thread, and was originally written back in the days of dotnet 1.1 - this explains the call to DoEvents. The code has been converted piece-wise to run in parallel in background threads through several different stages, with no one single developer having a complete overview of the process.
I am not sure I can replicate your issue, but this is how we get it and it work's just fine...
Try
'YOUR CODE'
Catch ex As Exception
'This is where we grab it from... It needs to be in this block to work...
System.Reflection.MethodInfo.GetCurrentMethod.ToString
End Try
Let me know how it work's out for you?
I have created a C++ DLL and I am using it in a C# application. How should I report errors?
Use exceptions and throw my errors, or print them on std::cout or std::cerr, or something else? If I issue an exception inside my DLL, will my C# application be able to catch it? What is the best course of action on this regard?
Here's an example output from C# using PInvoke to call a method which throws std::exception.
ex = System.Runtime.InteropServices.SEHException (0x80004005):
External component has thrown an exception.
at ConsoleTester.Program.throw_exception()
at ConsoleTester.Program.Main(String[] args) in ConsoleTester.cs:line 18
Note: In this case throw_exception() is the exposed native method and it called a sub-method, but you can't see that part of the stack trace. All you get for deepest stack frame is the native boundary.
So, it isn't perfect, but it does work. Returning error codes is probably the most standard way to handle this, but if you're the only consumer of the library it probably won't make much difference.
Note: stdin/stdout is generally the worst way to handle errors. The exception being that it's not so bad to write a custom error handling object or set of routines that everything in the application can access when something goes wrong. (The output from such an interface might sometimes be stdin/stdout or a file or whatever is useful as configured) think log4j or log4net here...
Generally, logging is only part of error handling. You've still got to signal other parts of your application to respond to adverse conditions and (hopefully) recover from them. Here, only error codes or exceptions really work well (and exceptions are to be minimized from main program flow anyways).
Don't print errors on stdout or stderr! You need to return errors programatically so the C# application has a chance to handle them. What if the host application is a GUI app?
Throwing exceptions from a C++ DLL is fraught with peril. Even if your application was C++, it would have to be compiled with the exact same compiler as the DLL, like #ebyrob said. Calling from C#, I'm not sure.
Best course of action is returning error codes.
It really depends on how strong the error is. Most libraries that I've seen will return a success or failure result value from their function calls that you can check for manually in your code when you use it. They usually provide another method that just retrieves the error message in case you want to see it.
Save throw exceptions for the really big stuff that you can't continue without, this will force people using your library to fix those errors (or at the very least, see that there is a big problem).
I would not recommend printing anything in the console window, it is a very slow operation and having it in there forces anyone using your library to have that overhead with little option for optimization. If they want to print the error messages, they can just retrieve the error data from your library and print them out themselves.
The question arrived when I began having some strange symptoms on my computer.
Here's what's happening: I have a WinForms application written in C# (.Net 2.0). If I run it from Visual Studio 2005 (either Debug or Release), everything is just fine. If I try to run it from Windows (run the exact same executable generated by the debug process in VS 2005) I get a
"System.TypeInitializationException" on the Program class.
I have added debug log messages ( File.AppentAllText() ) in a static constructor and in Main(). The log messages in the static constructor get written, but the ones in Main() don't. So, clearly, something happens after the static constructor has finished and before the call to Main() is issued.
Any suggestions on where to look next? What happens before the Main() method is called?
Thanks everybody.
EDIT: I think that I should point out that the application runs just fine on other computers. :)
Check out your code in static constructors. TypeInitializationException usually happens when there is an exception in static constructor, so type cannot be initialized. Code can work fine in IDE because it was started from different user with different security privileges.
As a side note - I would avoid using of static constructors when it is possible.
Based on the exception it sounds like either a static constructor or the initialization of a static field is throwing an unhanded exception here. Given that the Main method is apparently not executing it's likely happening for a type which is referenced in the Main method and hence trying to be initialized by the CLR.
There are a couple of ways to track down what is causing this. None of them are pretty
Inspect the Main method of the program and analyze every Type in play and then analyze their static constructors to see which could be throwing
Systematically comment out lines in the Main method to discover which one is causing the exception
Or alternatively when you run the program it should popup an error dialog. At that point attach to the process and dig into the exception to see which type is causing the problem.
You will also get a System.TypeInitializationException when you have a error in a *.config file. Check the innerException for the LineNumber in that case.
I have a com interop c++ dll that is loaded in c++ throught the .tlb file generated in c#.
When I run in my computer it works fine but when I run in a computer that just got formated it gives:
WindowsError: exception code 0xe0434f4d
Do I have to do something for the .tlb file or its dll to be registered in the system? Something regarding regasm.exe?
If so, it is possible to only download regasm.exe and use it?
Sorry, you're a million miles from diagnosing this correctly. Type libraries are for compilers, they are not (usually) needed at runtime.
The exception code you are getting shows what is going wrong. It is the exception code for a managed exception. In other words, your C# code is throwing an exception and it isn't being handled. Which is pretty common for C# code, when it finds a problem that it doesn't know how to handle then it throws instead of plodding on generating garbage data.
There are two basic ways to tackle this. The Q&D approach is to use a debugger switched to managed mode and make it stop on an unhandled managed exception. Debug + Exception, Thrown check box, for example. Or you could add some diagnostics to the method itself, logging the error in a catch block for example.
Start with Q&D, it is almost always something silly, like FileNotFound.