为啥我的应用程序在发布模式下崩溃但在调试模式下不崩溃?

Posted

技术标签:

【中文标题】为啥我的应用程序在发布模式下崩溃但在调试模式下不崩溃?【英文标题】:Why does my application crash in release mode but not in debug mode?为什么我的应用程序在发布模式下崩溃但在调试模式下不崩溃? 【发布时间】:2012-08-20 22:00:36 【问题描述】:

发布模式和调试模式有什么区别?

如何在发布模式下调试以查看失败的原因?

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);
        
    

【问题讨论】:

【参考方案1】:

您的 sn-p 中的 catch 子句永远不会在您的应用的发布版本中捕获任何内容。当您在附加调试器的情况下运行它时,它确实工作。

您缺少的是 Application.ThreadException 的行为方式。只要检测到任何未处理的异常,就会触发该事件。但是,当您调试代码时,此功能启用。没有安装异常处理程序来引发事件。这样做是为了让您有一种体面的方式来调试未处理的异常。您的代码更改了该行为,现在 有一个 try 块处于活动状态,您的 catch 处理程序会收到异常。

要使代码以相同的方式运行,您需要更改未处理的异常处理策略。像这样:

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

现在您的 catch 子句将始终捕获异常。只要它在主线程上引发,它就不会捕获在工作线程中引发的异常。考虑使用此代码进行统一处理:

    [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));
    

【讨论】:

【参考方案2】:

我的经验告诉我,您应该寻找处理任何类型设置的代码。

您可以通过在注册表中没有设置且在 application.config 中没有设置的情况下调试您的应用程序开始。

如果您的应用程序使用数据库,您也应该尝试使用空数据库。

第二步是在你同事的电脑上调试你的应用程序。

希望这对你的探索有所帮助。

【讨论】:

同意。损坏的设置文件通常是我的原因。搜索并删除与此应用程序相关的 user.config 文件。【参考方案3】:

发生这种情况的原因有很多,许多专业人士可以确认这是任何应用程序的经典错误,当您确定一切正常时就会出现很好,但在客户端机器上不起作用。

如果没有问题中提供的任何异常细节,很难说为什么会发生这种情况。

顺便说一句,您可以通过从 Visual Studio 附加到应用程序来调试应用程序。

How to: Attach to a Running Process

【讨论】:

感谢您的回答,但您能解释一下为什么我上面的代码甚至没有捕捉到这个异常吗?它只是崩溃,而不是异常,没有消息框或任何东西 @armin EventViewer 说什么? 嗯,有些类型的异常是try/catch 无法发现的,例如***。看看EventViewer,就像 L.B 建议的那样,或者Enable First Chance Exceptions 看看会发生什么。 @L.B 应用程序:Mindry.exe 框架版本:v4.0.30319 描述:进程因未处理的异常而终止。异常信息:System.BadImageFormatException @armin:你是在另一台机器上以release模式运行还是在你开发的同一台机器上运行?【参考方案4】:

调试和发布模式是构建代码的两种不同方式。由于您使用的几乎每个开发环境的具体方式都不同,因此无法立即判断。这些模式也可以称为模式 1 和模式 2。

但是,您的调试模式可能会将调试信息(符号表、行号等)编译到您的二进制文件中,而 release 不会。但可能存在数千种差异。

尝试查找指定调试/发布模式的位置,您会发现不同之处!

【讨论】:

【参考方案5】:

找到任何环境选项的最佳方法是记录生产中发生的情况。从捕获和记录异常开始,然后将您学到的知识用于更具体的记录。

有关说明,请参阅 this Microsoft kb article。

关于发布和调试模式背后的想法:

存在发布模式和调试模式以允许不同的配置,一种设计帮助开发人员发现错误,另一种设计用于优化性能,并针对生产环境进行配置。

了解差异的最佳方法是调出您的项目构建属性(右键单击您的项目,选择属性,然后单击左侧的构建选项卡)。查看可以根据配置更改的所有不同选项。

调试与发布的另一个常见问题是未在您的某个项目项(例如配置文件或嵌入式资源)上设置正确的构建操作

【讨论】:

以上是关于为啥我的应用程序在发布模式下崩溃但在调试模式下不崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

为啥消息处理程序在调试模式下不起作用?

此代码在调试模式下工作,但在发布模式下不工作 c++

谷歌地图在发布模式下不工作,但在调试模式下工作正常

为啥我的程序在发布模式下运行良好,但在调试模式下失败? [关闭]

选择发布模式时应用程序崩溃但在调试模式下完美运行

react-native-geolocation-service 在调试模式下正常工作,但在发布模式下不工作