Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my application crash in release mode but not in debug mode?

What is the difference between release mode and debug mode?

And how can I debug in release mode to see whats failing?

class Program
{
    [STAThread]
    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainWindow());
        }
        catch (Exception ex)
        {
            Logger.Error("Main : "+ex.Message, typeof(Program));
            MessageBox.Show(ex.Message + ex.StackTrace);
            Environment.Exit(1);
        }
    }
}
like image 591
armin Avatar asked Aug 25 '12 18:08

armin


People also ask

What is one reason a program might work in debug mode but crash in Release mode?

This is usually caused because the debug build will initialize variables that you have not explicitly initialized. When you build in release mode these variables now contain a random value rather than the nice neat 0 (NULL) value that debug mode set for you.

Is Release mode faster than debug?

Lots of your code could be completely removed or rewritten in Release mode. The resulting executable will most likely not match up with your written code. Because of this release mode will run faster than debug mode due to the optimizations.

Should I use debug or Release?

In general, ALWAYS deploy Release builds to production. Debug will add to your assembly weight and degrade performance.

What is the difference between debug and Release mode?

By default, Debug includes debug information in the compiled files (allowing easy debugging) while Release usually has optimizations enabled. As far as conditional compilation goes, they each define different symbols that can be checked in your program, but they are language-specific macros.


1 Answers

The catch clause in your snippet will never catch anything in the shipping version of your app. It does work when you run it with a debugger attached.

What you are missing is the way Application.ThreadException behaves. That event fires whenever any unhandled exception is detected. This feature however is not enabled when you debug your code. No exception handler is installed to raise the event. This was done so you have a decent way to debug unhandled exceptions. Your code changes that behavior, now there is a try block active, your catch handler gets the exception.

To get the code to behave the same way, you'll need to change the unhandled exception handling strategy. Like this:

    [STAThread]
    static void Main() {
        try {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
            Application.Run(new Form1());
        }
        catch (Exception ex) {
            // etc..
        }
    }

Now your catch clause will always catch the exception. As long as it is raised on the main thread, it won't catch exceptions raised in worker threads. Consider this code instead for unified handling:

    [STAThread]
    static void Main() {
        AppDomain.CurrentDomain.UnhandledException += AllUnhandledExceptions;
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        Application.Run(new Form1());
    }

    private static void AllUnhandledExceptions(object sender, UnhandledExceptionEventArgs e) {
        var ex = (Exception)e.ExceptionObject;
        // Display or log ex.ToString()
        //...
        Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
    }
like image 139
Hans Passant Avatar answered Sep 21 '22 07:09

Hans Passant