C# 在异常时中断调试器作为"Break When Thrown"



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

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

然而,这段代码在ExceptionHandler时中断,而不是在抛出位置。如何在投掷位置断裂?

我不想更改异常设置,因为我想中断达到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"

这称为首次机会异常处理程序。下面是一个示例:

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://learn.microsoft.com/en-us/dotnet/framework/app-domains/how-to-receive-first-chance-exception-notifications

命中第一次机会异常时的调用堆栈将显示"throw"作为调用堆栈上的先前位置。

更新:

第二次机会异常不会在"抛出"期间处理。这是根据定义。堆栈跟踪具有抛出位置。

所以你可以 - 第一次机会就中断,忽略你不关心的异常(只是重新抛出它们( - 中断第二次机会异常并检查堆栈跟踪以确定它们来自何处

你不能用第二次机会处理程序打破"投掷"。这不是他们的工作方式。

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

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

从菜单栏中,选择"调试> Windows>例外设置"。

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

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

从菜单栏中,选择"调试">"附加到进程...然后按进程 ID 找到应用程序或 Web 应用池。

(注意:如果要进行远程调试,请将远程调试器从 Visual Studio 的安装目录复制到远程计算机,并在管理员处运行它,以便 Visual Studio 可以连接。 通常,它默认为端口 4020。

最新更新