Is it possible not have the debugger stop at the throw statement, while keeping the same functionality?
I've asked around and it seems not, but I thought I'd give stackoverflow a try before I accept that's it's not possible.
class Program
{
static void Main(string[] args)
{
var o = new MyClass();
var t = new Task(o.DoStuff);
t.Start();
try
{
t.Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
}
public class MyClass
{
public void DoStuff()
{
throw new Exception("Testing"); // debugger stops here!
}
}
Open Exceptions windows with Ctrl + Alt + E in Visual Studio. Click on which exception you want to unhandled.
Also check: Visual Studio: How to break on handled exceptions?
Related
Related to this question, I would like to force CLR to let my .NET 4.5.2 app catch Corrupted State Exceptions, for the sole purpose of logging them and then terminating the application. What's the correct way to do this, if I have catch (Exception ex) at several places around the app?
So, after I specify the <legacyCorruptedStateExceptionsPolicy> attribute, if I understood correctly, all the catch (Exception ex) handlers will catch exceptions like AccessViolationException and happily continue.
Yeah, I know catch (Exception ex) is a Bad Idea™, but if CLR would at least put the correct stack trace into the Event Log, I would be more than happy to explain to the customer that his server app failing fast at 1AM and being offline for the night is a good thing. But unfortunately, CLR logs an unrelated exception into the Event Log and then closes the process so that I cannot find out what actually happened.
The question is, how to make this happen, process wide:
if the exception thrown is a Corrupted State Exception:
- write the message to the log file
- end the process
(Update)
In other words, this would probably work for most exceptions in a simple app:
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
static void Main() // main entry point
{
try
{
}
catch (Exception ex)
{
// this will catch CSEs
}
}
But, it won't work for:
Unhandled app domain exceptions (i.e. thrown on non-foreground threads)
Windows Service apps (which don't have an actual Main entry point)
So it seems like <legacyCorruptedStateExceptionsPolicy> is the only way to make this work, in which case I don't know how to fail after logging the CSE?
Instead of using <legacyCorruptedStateExceptionsPolicy> it would be better to use [HandleProcessCorruptedStateExceptions] (and [SecurityCritical]) as stated here:
https://msdn.microsoft.com/en-us/magazine/dd419661.aspx
Following that, your Main method should look something like this:
[HandleProcessCorruptedStateExceptions, SecurityCritical]
static void Main(string[] args)
{
try
{
...
}
catch (Exception ex)
{
// Log the CSE.
}
}
But be aware that this doesn't catch the more serious exceptions like StackOverflowException and ExecutionEngineException.
Also finally of involved try blocks will not be executed:
https://csharp.2000things.com/2013/08/30/920-a-finally-block-is-not-executed-when-a-corrupted-state-exception-occurs/
For other unhandled appdomain exceptions you can use :
AppDomain.CurrentDomain.UnhandledException
Application.Current.DispatcherUnhandledException
TaskScheduler.UnobservedTaskException
(Please do a search for the details when a specific handler is appropriate for your situation. TaskScheduler.UnobservedTaskException for example is a bit tricky.)
If you don't have access to the Main method, you can also mark your AppDomain exception handler to catch the CSE:
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
...
[HandleProcessCorruptedStateExceptions, SecurityCritical]
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// AccessViolationExceptions will get caught here but you cannot stop
// the termination of the process if e.IsTerminating is true.
}
The last line of defense could be an unmanaged UnhandledExceptionFilter like this:
[DllImport("kernel32"), SuppressUnmanagedCodeSecurity]
private static extern int SetUnhandledExceptionFilter(Callback cb);
// This has to be an own non generic delegate because generic delegates cannot be marshalled to unmanaged code.
private delegate uint Callback(IntPtr ptrToExceptionInfo);
And then somewhere at the beginning of your process:
SetUnhandledExceptionFilter(ptrToExceptionInfo =>
{
var errorCode = "0x" + Marshal.GetExceptionCode().ToString("x2");
...
return 1;
});
You can find more information about the possible return codes here:
https://msdn.microsoft.com/en-us/library/ms680634(VS.85).aspx
A "specialty" of the UnhandledExceptionFilter is that it isn't called if a debugger is attached. (At least not in my case of having a WPF app.) So be aware of that.
If you set all the appropriate ExceptionHandlers from above, you should be logging all exceptions that can be logged. For the more serious exceptions (like StackOverflowException and ExecutionEngineException) you have to find another way because the whole process is unusable after they happened. A possible way could perhaps be another process that watches the main process and logs any fatal errors.
Additional hints:
In the AppDomain.CurrentDomain.UnhandledException you can safely cast the e.ExceptionObject to Exception without having to worry - at least if you don't have any IL code that throws other objects than Exception: Why is UnhandledExceptionEventArgs.ExceptionObject an object and not an Exception?
If you want to suppress the Windows Error Reporting dialog, you can take a look here: How to terminate a program when it crashes? (which should just fail a unit test instead of getting stuck forever)
If you have a WPF application with multiple dispatchers you can also use a Dispatcher.UnhandledException for the other dispatchers.
Thanks to #haindl for pointing out that you can also decorate handler methods with the [HandleProcessCorruptedStateExceptions]1 attribute, so I made a little test app just to confirm if things really work as they are supposed to.
1 Note: Most answers state that I should also include the [SecurityCritical] attribute, although in the tests below omitting it didn't change the behavior (the [HandleProcessCorruptedStateExceptions] alone seemed to work just fine). However, I will leave both attributes below since I am presuming all these folks knew what they were saying. That's a school example of "Copied from StackOverflow" pattern in action.
The idea is, obviously, to remove the <legacyCorruptedStateExceptionsPolicy> setting from app.config, i.e. only allow our outermost (entry-level) handler(s) to catch the exception, log it, and then fail. Adding the setting will allow your app to continue, if you catch the exception in some inner handler, and this is not what you want: the idea is just to get the accurate exception info and then die miserably.
I used the following method to throw the exception:
static void DoSomeAccessViolation()
{
// if you have any questions about why this throws,
// the answer is "42", of course
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
}
1. Catching exceptions from Main:
[SecurityCritical]
[HandleProcessCorruptedStateExceptions]
static void Main(string[] args)
{
try
{
DoSomeAccessViolation();
}
catch (Exception ex)
{
// this will catch all CSEs in the main thread
Log(ex);
}
}
2. Catching all exceptions, including background threads/tasks:
// no need to add attributes here
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
// throw on a background thread
var t = new Task(DoSomeAccessViolation);
t.Start();
t.Wait();
}
// but it's important that this method is marked
[SecurityCritical]
[HandleProcessCorruptedStateExceptions]
private static void UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// this will catch all unhandled exceptions, including CSEs
Log(e.ExceptionObject as Exception);
}
I would recommend using just the latter approach, and removing the [HandleProcessCorruptedStateExceptions] from all other places to make sure the exception doesn't get caught at the wrong place. I.e. if you have a try/catch block somewhere and an AccessViolationException is thrown, you want CLR to skip the catch block and propagate to the UnhandledException before ending the app.
Is party over? not so fast
Microsoft: "Use application domains to isolate tasks that might bring down a process."
The program below will protect your main application/thread from unrecoverable failures without risks associated with use of HandleProcessCorruptedStateExceptions and <legacyCorruptedStateExceptionsPolicy>
public class BoundaryLessExecHelper : MarshalByRefObject
{
public void DoSomething(MethodParams parms, Action action)
{
if (action != null)
action();
parms.BeenThere = true; // example of return value
}
}
public struct MethodParams
{
public bool BeenThere { get; set; }
}
class Program
{
static void InvokeCse()
{
IntPtr ptr = new IntPtr(123);
System.Runtime.InteropServices.Marshal.StructureToPtr(123, ptr, true);
}
// This is a plain code that will prove that CSE is thrown and not handled
// this method is not a solution. Solution is below
private static void ExecInThisDomain()
{
try
{
var o = new BoundaryLessExecHelper();
var p = new MethodParams() { BeenThere = false };
Console.WriteLine("Before call");
o.DoSomething(p, CausesAccessViolation);
Console.WriteLine("After call. param been there? : " + p.BeenThere.ToString()); //never stops here
}
catch (Exception exc)
{
Console.WriteLine($"CSE: {exc.ToString()}");
}
Console.ReadLine();
}
// This is a solution for CSE not to break your app.
private static void ExecInAnotherDomain()
{
AppDomain dom = null;
try
{
dom = AppDomain.CreateDomain("newDomain");
var p = new MethodParams() { BeenThere = false };
var o = (BoundaryLessExecHelper)dom.CreateInstanceAndUnwrap(typeof(BoundaryLessExecHelper).Assembly.FullName, typeof(BoundaryLessExecHelper).FullName);
Console.WriteLine("Before call");
o.DoSomething(p, CausesAccessViolation);
Console.WriteLine("After call. param been there? : " + p.BeenThere.ToString()); // never gets to here
}
catch (Exception exc)
{
Console.WriteLine($"CSE: {exc.ToString()}");
}
finally
{
AppDomain.Unload(dom);
}
Console.ReadLine();
}
static void Main(string[] args)
{
ExecInAnotherDomain(); // this will not break app
ExecInThisDomain(); // this will
}
}
I want to return a default int value from main.
Consider the following:
using System;
class Class1
{
static int Main(string[] args)
{
int intReturnCode = 1;
int intRandNumber;
Random myRandom = new Random();
intRandNumber = myRandom.Next(0,2);
if(intRandNumber ==1)
{
throw new Exception("ErrorError");
}
return intReturnCode;
}
}
When the exception is reached I don't get to set the returncode.
Is it possible to have a default return code inside of main?
Clarification: I have a program that is throwing Unhandled Exceptions. I have the application inside a try catch, however some errors (probably out of memory, stackoverflow etc) are still bubling up and causing my application to fail in production.
To fix this I've added code to capture unhandled exceptions.
This was added to main:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
And now I have this method that is reached when an unhandled exception occurs.
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
}
The prblem is that I'm no longer in Main and I want to exit with a non-zero exit code.
An unhandled exception is implementation defined behaviour. Anything can happen; the CLR can decide to set the return code of the process as it sees fit, it can start a debugger, it can do whatever it wants. You cannot rely on any behaviour of any program that contains an unhandled exception.
If you want to have predictable behaviour, like determining what the return code is when the process ends, then there must be a total of zero unhandled exceptions.
If you have a third party component that is throwing unhandled out of memory exceptions then your best bet is: fix the bug in that component. If you can't do that then isolate the component into its own process or its own appdomain.
The question is really why you are throwing an exception in main instead of providing a return code that indicates an error? Instead of what you're doing, my code would look as follows:
static int Main(string[] args)
{
int intRandNumber;
try
{
Random myRandom = new Random();
intRandNumber = myRandom.Next(0,2);
if(intRandNumber ==1)
{
Console.WriteLine("Got invalid random number!");
return 0;
}
}
catch (Exception exp)
{
Console.WriteLine("Strange ... an error occurred! " + exp.ToString());
return -1;
}
return 1;
}
As a rule of thumb you should never throw exceptions to control program flow. If you can, handle conditions like oops, I got the wrong number without throwing an exception.
Throwing an exception in the main thread ends execution without reaching the return: that's when you get the "Console application has stopped working, would you like to debug?" dialog from the operating system. The Main cannot return anything under these conditions, because there is nothing to return.
If you would like to return something when you get an exception, code your program like this:
// Put your implementation into a private method
private static int DoWork(string[] args) {
... // Do actual work, and throw exceptions if you need to
return intReturnCode;
}
// The Main method calls the implementation, and returns the value
// returned from the implementation if everything goes well.
// If an exception is thrown, however, Main could return another value
// of its choice.
public static int Main(string[] args) {
try {
return DoWork(args);
} catch {
return myDefaultReturnCode;
}
}
catch your exception and set return statement in finally block
using System;
class Class1
{
static int Main(string[] args)
{
try
{
int intReturnCode = 1;
int intRandNumber;
Random myRandom = new Random();
intRandNumber = myRandom.Next(0,2);
if(intRandNumber ==1)
{
throw new Exception("ErrorError");
}
}
catch(Exception e)
{
// ...
}
finally
{
return intReturnCode;
}
}
}
I have this code:
using System;
using System.Runtime.Remoting.Messaging;
class Program {
static void Main(string[] args) {
new Program().Run();
Console.ReadLine();
}
void Run() {
Action example = new Action(threaded);
IAsyncResult ia = example.BeginInvoke(new AsyncCallback(completed), null);
// Option #1:
/*
ia.AsyncWaitHandle.WaitOne();
try {
example.EndInvoke(ia);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
*/
}
void threaded() {
throw new ApplicationException("Kaboom");
}
void completed(IAsyncResult ar) {
// Option #2:
Action example = (ar as AsyncResult).AsyncDelegate as Action;
try {
example.EndInvoke(ar);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
In many articles stands that when I call BeginInvoke, all Exceptions (here from method threaded) wait until I call EndInvoke and will be thrown there. But it doesn't work, the Exception ("Kaboom") is "unhandled" and the program crashes.
Can you help me?
Thanks!
That works fine. When you say "and the program crashes", I'm wondering if you just have the IDE set to break on all exceptions. I get no crash with that - it writes "Kaboom" to the console, as we would expect. Try running it outside of the IDE or pressing ctrl+f5 instead of just f5.
I think you are just seeing the IDE being "helpful":
Ignore that; the IDE doesn't always get it right. That is still handled.
Which one is better in structure?
class Program
{
static void Main(string[] args)
{
try
{
using (Foo f = new Foo())
{
//some commands that potentially produce exceptions.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
or...
class Program
{
static void Main(string[] args)
{
using (Foo f = new Foo())
{
try
{
//some commands that potentially produce exceptions.
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Either is fine, depending on what you are going to do in the catch. If you need to use f in your catch then it needs to be within the using statement. However in your example there is no difference.
EDIT:
As pointed out elsewhere it also depends on whether you are trying to catch just exceptions generated in the block following the using or including the object creation in the using statement. If it is in the block following the using then it is as I described. If you want to catch exceptions generated by Foo f = new Foo() then you need to use the first method.
I don't think it matters much, performance-wise. There is a slight difference though; in the second example, f is still available inside the exception handler, while in the first, it has gone out of scope. Conversely, in the first example, exceptions in the Foo constructor as well as its Dispose method will be caught, while in the second, they won't.
Either may or may not be what you want.
Check this post to understand better : http://www.ruchitsurati.net/index.php/2010/07/28/understanding-%E2%80%98using%E2%80%99-block-in-c/
Also read answers of this question : Catching exceptions thrown in the constructor of the target object of a Using block
the first one is bettwer one
class Program
{
static void Main(string[] args)
{
try
{
using (Foo f = new Foo())
{
//some commands that potentially produce exceptions.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
because if you see the IL code of this try and catch block not wrap the inialization of the object.
The first is better, because it will catch any exceptions thrown during the dispose process. Of course, you shouldn't throw any exceptions when disposing, but stuff happens.
First one is the better one .if any exception comes it will catch.
try
{
using (Foo f = new Foo())
{
//some commands that potentially produce exceptions.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The concept of using is it will dispose the object created in the using.i.e it automatically calls the IDispose method.Based on the requirement use the using.
Using is just
Foo f = null;
try
{
f = new Foo();
}
finally
{
if (f is IDisposable)
f.Dispose();
}
Seeing that you can achive catching exceptions like this:
Foo f = null;
try
{
f = new Foo();
}
catch (Exception ex)
{
// handle exception
}
finally
{
if (f is IDisposable)
f.Dispose();
}
I have a command line program in C# that I've wrapped with a try-catch block to keep it from crashing the console. However, while I am debugging it, if an exception is thrown somewhere in the DoStuff() method, Visual Studio will break on the "catch" statement. I want Visual Studio to break where the exception occurred. What's the best way to do this?
Comment out the try?
A setting in Visual Sudio?
An #if DEBUG statement?
static void Main(string[] args)
{
try
{
DoStuff();
}
catch (Exception e)
{ //right now I have a breakpoint here
Console.WriteLine(e.Message);
}
}
private void DoStuff()
{
//I'd like VS to break here if an exception is thrown here.
}
You can turn on First chance exceptions in VS. This will allow you to be notified as soon as an exception is raised.
I think setting VS to break on uncaught exceptions and wrapping the try/catch in ifdefs is how I would go about doing it.
There is an option to "Break on all exceptions". I'm not sure what version of VS you are using but in VS 2008 you can press Ctrl + D, E. You can then click the checkbox the Thrown checkbox for the types of exceptions you want to break on
I believe in previous versions of VS there was a Debug menu item to the effect of "Break on all exceptions". Unfortunately I don't have a previous version handy.
Here's how I do it for console tools running at continuous integration server:
private static void Main(string[] args)
{
var parameters = CommandLineUtil.ParseCommandString(args);
#if DEBUG
RunInDebugMode(parameters);
#else
RunInReleaseMode(parameters);
#endif
}
static void RunInDebugMode(IDictionary<string,string> args)
{
var counter = new ExceptionCounters();
SetupDebugParameters(args);
RunContainer(args, counter, ConsoleLog.Instance);
}
static void RunInReleaseMode(IDictionary<string,string> args)
{
var counter = new ExceptionCounters();
try
{
RunContainer(args, counter, NullLog.Instance);
}
catch (Exception ex)
{
var exception = new InvalidOperationException("Unhandled exception", ex);
counter.Add(exception);
Environment.ExitCode = 1;
}
finally
{
SaveExceptionLog(parameters, counter);
}
}
Basically, in release mode we trap all unhandled exceptions, add them to the global exception counter, save to some file and then exit with error code.
In debug more exception goes right to the throwing spot, plus we use console logger by default to see what's happening.
PS: ExceptionCounters, ConsoleLog etc come from the Lokad Shared Libraries