C#在异常时打破调试器"抛出时断开"

时间:2018-06-12 13:49:02

标签: c# exception-handling visual-studio-debugging

在我的asp.net应用程序中,如果应用程序抛出异常,则会被捕获,而是提供500页。我想在throw位置打破调试器。目前我正在使用以下代码段:

           void ExceptionHandler(Exception ex) {
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }}

但是此代码在ExceptionHandler处断开,而不是在throw位置。我怎样才能在投掷地点突破?

我不想更改异常设置,因为我希望中断到达ExceptionHandler的异常,而不是系统恢复的异常。

为了更好地说明我的问题:

class Server // Server owned by third party
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.FirstChanceException += (source, e) =>
        {
            // This does not help, because there are legit exceptions
            Console.WriteLine("FirstChanceException event raised in {0}: \"{1}\"",
                AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
        };
        AppDomain.CurrentDomain.UnhandledException += (source, e) =>
        {
            // This does not help, because exception should be handled by server, otherwise it would shut down
            Console.WriteLine("UnhandledException event raised in {0}: \"{1}\"",
                AppDomain.CurrentDomain.FriendlyName, e.ExceptionObject);
        };

        var app = new Application();
        while (true)
        {
            try
            {
                app.ProcessRequest();
            }
            catch (Exception e)
            {
                // If we get here this mean that something is wrong with application
                // Let's break on line marked as #1
                Console.WriteLine("Server swallowed an exception \"{0}\"", e.Message);
                Debugger.Break(); // Debugger breaks, but no exception dialog, and stack trace in method main
            }
        }
    }
}

class Application
{
    public void ProcessRequest()
    {
        try
        {
            Console.WriteLine("Doing stuff");
            throw new InvalidOperationException("Legit exception handled by application");
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine("Application handled exception \"{0}\"", ex.Message);
        }

        throw new InvalidOperationException("Unhandled exception"); // #1. Something is wrong here
    }
}

计划的输出:

Doing stuff
FirstChanceException event raised in ExceptionTest: "Legit exception handled by application"
Application handled exception "Legit exception handled by application"
FirstChanceException event raised in ExceptionTest: "Unhandled exception"
Server swallowed an exception "Unhandled exception"

2 个答案:

答案 0 :(得分:0)

您可以附加Visual Studio调试器(或远程调试器,如果它在单独的计算机上运行)。

步骤1:在Visual Studio IDE中配置设置。

从菜单栏中选择Debug> Windows>例外设置。

如果选择所有异常,这将导致调试器在连接到正在运行的进程时,在每个异常(处理和未处理)之前中断

步骤2:附加到您的进程以在Visual Studio(本地或远程)中调试它。

从菜单栏中选择Debug>附加到流程...然后按流程ID找到您的应用程序或Web应用程序池。

(注意:如果您是远程调试,则将远程调试器从Visual Studio的安装目录复制到远程计算机并在Administrator上运行,以便Visual Studio可以连接。通常默认为端口4020.)

答案 1 :(得分:0)

这被称为第一次机会异常处理程序。这是一个例子:

static void Main(string[] args)
    {
        AppDomain.CurrentDomain.FirstChanceException +=
        (object source, FirstChanceExceptionEventArgs e) =>
        {
            Console.WriteLine("FirstChanceException event raised in {0}: {1}",
                AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
        };

        try
        {
            Console.WriteLine("Doing stuff");
            throw new ArgumentNullException("Super awesome exception");
        }
        catch (Exception e)
        {
            Console.WriteLine("Caught an exception {0}", e.Message);
        }
    }

或者在msdn文档中看到这个: https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-receive-first-chance-exception-notifications

当遇到firstchance异常时,callstack会将“throw”显示为callstack上的前一个位置。

<强>更新

在“投掷”期间不会处理第二次机会异常。这是定义。 stacktrace具有throw位置。

所以你也可以 - 打破第一次机会并忽略你不关心的例外(只需重新抛出它们) - 打破第二次机会异常并检查堆栈跟踪以确定它们来自哪里

你不能用第二次机会处理程序打破“抛出”。这不是他们的工作方式。