Bug in CLR? CLR execution engine failed - c#

AFAIK, try and finally block are used execute a piece of code that might throw some exception, we also add catch block if we are prepared to handle some type of exception and/or are excepting them, like FileIOException, AccessRight or something. But when I ran this..
private void button1_Click(object sender, EventArgs e)
{
try
{
Environment.FailFast("It failed");
}
finally
{
MessageBox.Show("Done");
}
}
Its breaks with an exception and says
FatalExecutionEngineError was detected
Message: The runtime has encountered a fatal error. The address of the error was at 0x032526f4, on thread 0xd04. The error code is 0x80131623. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
Now msdn says
Usually, when an unhandled exception ends an application, whether or
not the finally block is run is not important. However, if you have
statements in a finally block that must be run even in that situation,
one solution is to add a catch block to the try-finally statement.
So, I added the catch block, but still it says the same thing.
private void button1_Click(object sender, EventArgs e)
{
try
{
Environment.FailFast("It failed");
}
catch (Exception ex)
{
}
finally
{
MessageBox.Show("Done");
}
}
It failed again with the same error. As for CLR saying the code block in finally always runs (at least when catch is added), it surely is not the case. Reviews/Opinions anyone?
Also here's the snapshot..

This is by design. The purpose of Environment.FailFast is to halt execution immediately. By design it will not run any code in catch or finally blocks.
The documentation says:
This method terminates a process without running any active
try/finally blocks or finalizers.
The FailFast method writes the message string to the Windows
Application event log, creates a dump of your application, and then
terminates the current process. The messa string is also included in
error reporting to Microsoft.
Use the FailFast method instead of the Exit method to terminate your
application if the state of your application is damaged beyond repair,
and executing your application's try/finally blocks and finalizers
will corrupt program resources.
This makes it clear that code in your finally blocks will not run. If there was a way to make code run after Environment.FailFast then that would render Environment.FailFast pretty much useless. Its very existence is predicated on the fact that your code does not execute after you call it.
You point to documentation that states (emphasis mine):
Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement.
But those words simply do not apply here. You are assuming that when you call Environment.FailFast, an unhandled exception terminates the application. That is not the case. The application is just terminated on the spot – there is no unhandled exception.

Related

Finally block does not execute as Microsoft say in it's Doc

Here Microsoft says:
"By using a finally block, you can clean up any resources that are
allocated in a try block, and you can run code even if an exception
occurs in the try block."
and clearly use this sample to support that idea:
public class ThrowTestA
{
static void Main()
{
int i = 123;
string s = "Some string";
object obj = s;
try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;
// The following statement is not run.
Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// To run the program in Visual Studio, type CTRL+F5. Then
// click Cancel in the error dialog.
Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
"error depends on how the exception unwind operation is triggered.");
Console.WriteLine("i = {0}", i);
}
}
// Output:
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
//
// Execution of the finally block after an unhandled
// error depends on how the exception unwind operation is triggered.
// i = 123
}
but when I copied this to my .Net-Core console it doesn't execute finally and doesn't return the output in finally that I expect according to Microsoft says! it returns below and I don't know why!
I know that we can simply use try..catch block and resolve the problem. I just want to know this contradiction with Microsoft's sample and my experience!
And later on in the same paper they say
Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up.
in your case the exception is unhandled so finally is not guaranteed to be called
Check it here:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally
Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up.
Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement. Alternatively, you can catch the exception that might be thrown in the try block of a try-finally statement higher up the call stack. That is, you can catch the exception in the method that calls the method that contains the try-finally statement, or in the method that calls that method, or in any method in the call stack. If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.
When is this usually?
If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.
Exception unwind
When we enclose a block of code with a try statement compiler creates a step to store current context of the CPU in current stack frame with program counter pointed to start of catch block. If the CPU encounters any error it retrieves the context from stack an program counter jumps to catch statement.
Conditions when finally does not execute in a .net try..finally block
Some examples:
StackOverflowException
ExecutionEngineException
Application exit

.NET Core: Finally block not called on unhandled exception on Linux

I have created the following C# program:
namespace dispose_test
{
class Program
{
static void Main(string[] args)
{
using (var disp = new MyDisposable())
{
throw new Exception("Boom");
}
}
}
public class MyDisposable : IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
}
When I run this using dotnet run, I see the following behavior:
Windows: Exception text written to console, "Disposed" printed ~20 second later, program exits.
Linux: Exception text written to console, program exits immediately. "Disposed" never written.
The delay on Windows is annoying, but the fact that Dispose() isn't called at all on Linux is troubling. Is this expected behavior?
EDITS Clarifications/additions from the conversation below:
This is not specific to using/Dispose(), which is just a special case of try/finally. The behavior also occurs generally with try/finally - the finally block is not run. I have updated the title to reflect this.
I have also checked for the execution of Dispose() by writing a file to the filesystem, just to ensure that problem wasn't related to stdout being disconnected from the console before Dispose() is run in the case of an unhandled exception. Behavior was the same.
Dispose() does get called if the exception is caught anywhere within the application. It's when it goes completely unhandled by the application that this behavior occurs.
On Windows, the long gap is not due to compilation delay. I started timing when the exception text was written to the console.
My original experiment was doing dotnet run on both platforms, which means separate compilations, but I have also tried by doing dotnet publish on Windows and directly running the output on both platforms, with the same result. The only difference is that, when run directly on Linux, the text "Aborted (core dumped)" is written after the exception text.
Version details:
dotnet --version -> 1.0.4.
Compiling to netcoreapp1.1, running on .NET Core 1.1.
lsb-release -d -> Ubuntu 16.04.1 LTS
Official response is that this is an expected behavior.
Interestingly enough, the C# doc page on try-finally explicitly calls this out right at the top (emphasis mine)
Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up. For more information, see Unhandled Exception Processing in the CLR.
Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement. Alternatively, you can catch the exception that might be thrown in the try block of a try-finally statement higher up the call stack. That is, you can catch the exception in the method that calls the method that contains the try-finally statement, or in the method that calls that method, or in any method in the call stack. If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.
One thing I found in my experimentation is that it doesn't appear to be enough to catch the exception, you have to handle it as well. If execution leaves the catch block via a throw, the finally will not run.
If you surround this with a try-catch, the finally block will run when the exception is caught (handled) by the outer catch.
static void Main(string[] args)
{
try
{
using (var disp = new MyDisposable())
{
throw new Exception("Boom");
}
}
catch (Exception e)
{
throw;
}
}

Getting exception that caused program to crash without being in debug mode

I have an application in C# that I want to run by just running the .exe from my desktop. However, I'm pretty sure there will be some type of error that will make the program crash. Is there a way to write the problem that caused the program to crash to a text file, so that I can see what caused the issue when users are using the program? I know I can use debug mode to do this but I want to run the application as a stand alone not inside of VS.
Thanks,
I am aware of the try catch blocks and I am already using those where problems might occur. But I am speaking in general. For example if I wasn't sure where the problem would occur. There is no way to print this specific error to a file.
You can try the global try/catch method except that if there is an exception on a background thread it won't be caught. You can use AppDomain.UnhandledException if you want to be notified of any unhandled exception in the appdomain (msdn). You would signup in main before the rest of your program executes like so:
static void Main(string[] args)
{
AppDomain.UnhandledException += WriteUnhandledExceptionToFile;
// rest of program
}
static void WriteUnhandledExceptionToFile(object sender, UnhandledExceptionEventArgs args)
{
// write to where ever you can get it.
string path = Path.Combine(Environment.CurrentDirectory, "UnhandledException.txt");
File.WriteAllText(path, args.ExceptionObject.ToString()); // will print message and full stack trace.
}
Edit
Note that by default Windows Forms and WPF catch any exceptions that are thrown on the UI thread. You will have to subscribe to the Application.ThreadException event (forms) or Application.DispatcherUnhandledException event (wpf) to be notified of exceptions on those threads. The code would be very similar to the code above for the AppDomain event.
Have a global exception handler that writes the exception details to a file.
If you wrap the code in your Main method in a try{}catch{} block, you can write out the exception details in the catch block.
try
{
// Calls to application code
}
catch(Exception ex)
{
// log `ex.ToString()`
throw; // rethrow to ensure termination optionally: `Application.Exit`
}
Even if you aren't logging the problem, you can usually get the error in question from the event viewer within windows.
The first thing you want to look at is the try/catch construct in C#. This is probably your first building block to handling errors.
As for how you handle the errors, that's entirely up to you. Currently your only stated goal is to log them to a file. You can get a lot of details out of the Exception object that you catch and you can write those details to a file. Additionally, you can use logging libraries to help with that sort of thing.
Proper error handling is something of a big subject, really. One thing to keep in mind is logically where you want to catch the exception. Ideally, you want to catch it where you can handle it. That is, where your code can sufficiently recover from the error. If it's a fatal error and the application should stop entirely, then you can throw the exception further up the stack and let it go unhandled (though still logged where you caught it).
If, however, you're in a logical condition where you can just log the error and move on, then the catch block allows you to do just that. Log the details, update the state of any objects/data which need to be updated, and continue with the flow of the application.
you can surround your one of the starting method with try catch block
try
{
///Your code
}
catch(Exception exception)
{
System.IO.File.WriteAllLines("ErrLog.txt", exception.Message);
}
As a permanent solution you can create extension method ToLog and use it whenever you want.
public static void ToLog(this Exception Exception)
{
using (var file = File.AppendText("ErrorLog.txt"))
{
file.WriteLine(DateTime.Now + " : " + exception.Message);
}
}
You can use it in catch block like this
catch(Exception exception)
{
exception.ToLog();
}
See initial information here http://www.csharp-examples.net/catching-unhandled-exceptions/
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
}
The UnhandledException event handles uncaught exceptions thrown from the main UI thread. The ThreadException event handles uncaught exceptions thrown from non-UI threads.
I would replace the MessageBox with some actual logging (log4net or others). This would give you the ability to log out the errors to another server for distributed applications, file system for local users, event logs, options are fairly unlimited if you're willing to put in the time.

c# debugging windows crash

I have an app, and after about 20 minutes of idle time the program just crashes. ("Windows has encountered an error and needs to close...")
I have no idea why this is happening. What is the best way to go about debugging something like this?
Generally crashes in .Net applications are caused by an unhandled exception - i.e. an exception in a thread in that application that was not caught in a try-catch block of some sort:
try
{
// Some code that may throw an exception
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
A good first place to check for information about this exception is the application event log, often however you will find that the .Net framework posts only minimal information about the crash - if this is the case then you need to catch and handle the exception yourself, recording enough information to allow you to diagnose the error.
Typically there are two way that you might do this:
1. Ensure that the code for each thread of your application is contained in a try-catch block.
This is the easiest method - unless your application has multiple user threads (you will know if it has), this simply requires that you place a try-catch block around the entry point of your application, for example in a Windows Forms application:
// Probably found somewhere in Program.cs
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
If you are working on a console application then you will need to use something other than MessageBox (see the first example).
If you spawn multiple threads then the entry point method for each thread should also catch all exceptions in a similar way.
2. Handle the UnhandledException event of the current App Domain
This event will be fired whenever any thread throws an unhandled exception in the current App Domain. Generally speaking it is best to use the first method instead, however this event is still useful in some situations.
Example:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// The rest of your application
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
}
Of course it is worth pointing out that the error still might not be caught by either of the above two methods (which is possible if the error is caused by a native module loaded in the same process), however this should probably do the trick.
Finally - Good luck!

Catching an Exception across treeview.Nodes.Add / treeview_AfterSelect event boundary

There is a place in my WinForms program that throws a MyOwnException.
void CodeThatThrowsMyOwnException()
{
...
throw new MyOwnException("Deep Inside");
...
}
Further up the stack, there is a simple try/catch block
try
{
CodeThatThrowsMyOwnException();
}
catch (MyOwnException moe)
{
MessageBox.Show("Hit this point in the code! Hurray!");
}
MessageBox.Show("Later, alligator.");
On a colleague's computer (running VS 2008 SP1 like me) the dialog box shows up. On my computer, it never catches the exception nor shows the dialog box. When I place a breakpoint deep inside the code (CodeThatThrowsMyOwnException) on the line that throws the Exception, it hits the breakpoint on the line. If I press F5 (Debug > Run) it skips passed my catch block and displays the "Later, alligator" message.
Actually pasting the "void CodeThatThrowsMyOwnException() { throw new MyOwnException("Shallow"); }" code into my code (instead of calling my real code) and literally calling "CodeThatThrowsMyOwnException();" in the try block does however get show the message in the catch block.
As far as I can tell, I am not creating any threads and I have looked for try {} catch {} blocks that catch all exceptions but cannot find any in the involved projects (and if they were in there, why would this catch block still work on my colleague's machine?)
Strangely enough running my code by double clicking the executable gives me an unhandled exception on my machine and the same on my colleague's machine. This is a clue that led me to try the following:
When I place a breakpoint at the throw MyOwnException("Deep Inside") line deep inside my code, the call stack contains a line "[External Code]" between my exception handler and the place where I call 'throw MyOwnException("Deep Inside")'. If I put a try/catch MyOwnException block further away from the throw (but on this side of the [External Code] I can still catch the exception, anywhere I place the try catch block (around relevant parts of the function chain):
try
{
CodeChain(...);
}
catch (DrawException de)
{
MessageBox.Show("Hurray!"); // being executed, but only on the 'throw' side of the [External Code] part of the call stack
}
However, when I step outside (below on the stack) the [External Code], the exception does not fire. This is unexpected:
try
{
treeview.Nodes.Add(treeNode); // triggers the aforementioned chain of code with MyOwnException thrown
}
catch (DrawException de) // no matter what I do, this will not handle my cursed MyOwnException
{
MessageBox.Show("Hurray!"); // not being executed
}
This is the heart of my problem: I can't move my catch up the call stack because I need to run lots of tests (see below).
I have a sort of hypothesis, which is that his debugger is magically lifting the exception across thread boundaries (or across external code, i.e. Windows GUI events) in his debugger, whereas in the other three situations (my debugger (without the 64 bit extensions) and also when either machine runs the EXE from windows explorer the exception) the exception is truly unhandled on that thread.
So how do I catch this exception? Re-engineer my whole system to avoid using treeview.AfterSelect? Clearly I don't understand the limitations of exceptions.
Potential problem?
I have a delegate in there to keep my system modular and reusable. Can exceptions be thrown "through" a delegate, across module boundaries?
What I'm trying to accomplish (Testing Harness) and why I need Exceptions
I'm using this in an automated test harness. I need to fix some really tough logical/algorithmic bugs in a complicated GUI system by replaying action scripts (text files) that find these exceptional circumstances and narrow the problem down. (There is probably no good workaround to this in my program, in terms of rewriting or refactoring the design: I need to catch these Exceptions in this QA phase, fix the bugs (tough algorithmic special cases) before I ship so I don't subject my users to such buggy software. It's not like I'm using exceptions for exotic control flow for for fun (cf. Int32.Parse).)
The treeview_AfterSelect is going to be called most of the time by what you're referring to as [External Code]. These will be the result of the user selecting a node or even when the form is loading and you're adding nodes (which I suspect might be happening on your unhandled exception).
If your AfterSelect handler is going to throw exceptions for some reason, you cannot rely on your calling code to handle those exceptions. Otherwise, any other way that AfterSelect gets called could result in an unhandled exception.

Categories

Resources