I have a rather simple C# program (no UI, just command line) that uses a 3rd party library (Abbyy's Finereader 8.1) to do some work and then exits.
Simple enough and works quite well. Recently however we've started getting the following error from the program:
Application Error : The instruction at
"0x2c0de46b" referenced memory at
"0x0732aa84".
A little digging shows that this is happening at the end of the C# code. Basically the last two lines are:
Console.WriteLine(message);
return statusCode;
The final console message is written and the output from the program is fine. Indeed, if it wasn't for the fact that this error keeps the program from fully terminating I could work around it.
We're running two scripts that invoke this program each on two machines. This happens at random (as far as I can tell) but usually at least one of (the 4 scripts) hits this each day. I thought that perhaps some kind of weirdness was happening for concurrent runs, but testing eliminated that.
Any thoughts on possible causes would be most welcome as I've run out of ideas.
Also if anyone knows of a way to have the program terminate when this happens, that would be useful.
"Application Error : The instruction at "0x2c0de46b" referenced memory at "0x0732aa84"."
This error implies memory corruption somewhere in your code, without the full code i cannot say more than this.
The place where the exception is risen is not important in this case of error. Try to take a look at your code, especially the code that calls the library.
Well... Troubleshooting dictates that I ask what changed, but I reckon you thought about that yourself. What version of the .NET framework are you using? What OS(es) does this problem occur on?
I belief that this exception is coming from some cleanup that the 3rd party library does. Did you contact their support? Can you try to explicitly unload the library and see if the error still occurs then?
Or... did you try adding an handler for unhandled exceptions? Might be worth a try...
public static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(
OnUnhandledException);
//some code here....
}
/// <summary>
/// Occurs when you have an unhandled exception
/// </summary>
public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//here's how you get the exception
Exception exception = (Exception)e.ExceptionObject;
//bail out in a tidy way and perform your logging
}
(example code by DoctaJonez)
Just throwing some things out there, since there doesn't seem to be a definite answer (yet).
Related
I have a segment of code:
try
{
//sniping out a bunch of irrelevant code here
result = cmd.ExecuteScalar();
onExecution?.Invoke(result);
return true;
}
catch (SQLiteException e)
{
if (e.ResultCode == SQLiteErrorCode.Corrupt)
{
CorruptionDetected?.Invoke(null, EventArgs.Empty);
}
//snip - else if {etc}
throw;
}
The problem: I have VS to set to break on all exceptions always all the time no matter what without exception. VS does this correctly and without problem on every other exception everywhere in the program EXCEPT for this one.
I know WHY the error happening. That is of absolutely no interest to me whatsoever and is unrelated.
What I want to know is why that problem seems to either not actually generate the exception or else isn't catching it. I know with 100% certainty that errors are happening. You can see them in the Events tab in the Diagnostic Tools window. They pile up there but at no point do I ever get a catchable exception, just useless garbage in the Events tab.
How do I deal with this? If the error (SQLite error (5): database is locked) is a problem, then why am I not getting an exception? If it's not a problem and it's getting eventually processed, why is it polluting my Events list?
The way it currently stands is just utterly unacceptable as it makes absolutely no sense. Either it's a problem in which case I should get an exception or it's not a problem in which case I don't want to be inundated with useless debug events.
I've recently investigating the same problem in our C#/C++ code. I ended up downloading the System.Data.SQLite source code and debugging the library. System.Data.SQLite DLL is a C# wrapper around the standard SQLite (C++) library.
The most important: System.Data.SQLite DLL uses exceptions, however SQLite uses return codes. The wrapper intercepts return codes from SQLite and transforms them into exceptions, if reasonable.
If SQLite code (SQLite.Interop) was compiled with INTEROP_LOG flag, the library only logs certain errors to standard output and doesn't (maybe by mistake??) notify the wrapper about this kind of error. Therefore wrapper is unaware of the problem and won't throw an exception.
More in depth:
If you mangage to download and compile the System.Data.SQLite library on your own, try setting a break-point in file SQLite.Interop\interop.c in function sqlite3InteropLogCallback. Your program will stop whenever the 'database is locked' error is encountered, however no exception will be throw.
I have a third party library that sometimes causes the AccessViolationException. I've marked the culprit line. I'd really like this method to fail gracefully so that my calling code can try it again in a short time, but at the moment, this exception brings down the whole application.
public static PlayerModel GetModel(int instanceId)
{
try
{
// New player model.
PlayerModel model = new PlayerModel();
// Fill.
model._flakyLibrary = new FlakyLibrary(instanceId); // **Sometimes crashes**
model.instanceId = instanceId;
// Return the new player model.
return model;
}
catch
{
// Try again in a bit - the game is not fully loaded.
return null;
}
}
One thought I had was to start a child process to run this bit of logic and have that crash gracefully if it needs to - I don't know how to do this, let alone have one process return this kind of object (my custom PlayerModel) to another process. I have exhausted searching Google and Stack Overflow (maybe I'm asking the wrong questions?).
Solution
Huge thanks to Theodoros. I've added the following attributes to the above method. The exception is now being caught.
[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions]
[System.Security.SecurityCritical]
P.S - I'm still fascinated to know about the multiple process solution if anyone knows what I should be researching? Many thanks again.
Another edit:
I found a solution to using multiple processes: NamedPipeServerStream.
An AccessViolationException is an exception typically raised when your process tries to access memory that's not its own. (Incidentally, a NullReferenceException is just an AccessViolationException at low addresses, served with a different name, to give you a hint as to what caused it.) Thus, it's reasonable to say that this is more or less what happens inside your program: a dereference of an invalid pointer (possibly a null pointer) or access beyond the boundaries of a particular buffer.
If you're not messing with pointers, your code is not responsible for the problem. The constructor you are invoking is responsible for doing something unsafe and invalid. If the library you're using is open source, you can go in and try to diagnose the problem yourself, by looking for suspicious behaviors like those described above. You can then go ahead and try to fix it (and possibly contribute your fix to the developers of that library).
If the above can't be done for any reason, there is a workaround. By default, managed code cannot catch an AccessViolationException, because it's a Corrupted State Exception (CSE), but you can opt-in to handling such exceptions either globally (by applying a fix described in another answer) or per method (by using the [HandleProcessCorruptedStateExceptions] attribute).
However, you'll have to understand the risks taken: your program will be attempting to recover from corrupted state. If you can, try not to use a library that forces you to do that at all.
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.
I'm getting a strange error on a SharpDX program I made.
The program contains one form MainForm, which inherits from SharpDX.Windows.RenderForm (I'm doing Direct3D 9). I have some logic that kills the program by calling MainForm.Close(), and it works perfectly.
However, when I close the form with the X button, or by double clicking the top left corner of the screen, the program ends with code -1073610751 (0xc0020001).
This is a relatively minor annoyance, because it only happens when the program is finishing, so it doesn't really matter if it exits with an error, because it is actually finishing.
However, this error does not happen when I set a breakpoint at the last line of my Main(). If I do so, and then close the window as I explained, the breakpoint gets hit, and resuming ends the program with code 0.
Apart from SharpDX and one pure C DLL I am calling to one-shot process some data, I am not doing mixed code, or any other weird stuff.
I've looked around, but this code appears to be related to string bindings? other people seem to have this problem when doing weird mixed C++/CLI stuff, but I'm not doing anything like that.
Any ideas? at least on how to get more concise information on this error code?
It is a very low-level RPC error. Which is likely to be used in your program, it is the underlying protocol on top of which COM runs. There are plenty of candidates, SharpDX itself uses the COM interop layer to make DirectX calls. And DirectX itself is very likely to make such kind of calls to your video driver.
It is also the kind of error code you'd expect to get triggered if there's a shutdown-order problem. Like using a COM interface after it was already released. Shutting down a program cleanly can be a difficult problem to solve, especially when there are lots of threads. There are in any DirectX app. It is also very easy to ignore such a problem, even if it is known and recorded in somebody's bug database. Because, as you noted, the program otherwise shuts down okay without any nasty exceptions. RPC already prevented it from blowing up, you are seeing the error code it generated.
There's very little you can do yourself about this problem, this is code you did not write and you'll never find the programmer who did. If you see a first-chance exception notification in the Output window then you could enable the unmanaged debugger, use Debug + Exceptions and tick the Thrown checkbox for Win32 exception, enable the Microsoft Symbol server and you'll get a stack trace when the exception is thrown. Beware this will be in the bowels of native code with no source to look at. But it could pin-point the DLL that's causing the problem. Still nothing you can do to fix that DLL. I'd recommend a video driver update, the most common source of trouble. That's about as far as you can take it.
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.