gpt4 book ai didi

c# - 显示重新抛出的异常的堆栈跟踪,而不是从抛出点开始的堆栈跟踪

转载 作者:行者123 更新时间:2023-11-30 13:29:23 26 4
gpt4 key购买 nike

我已经在 VS2005 中确认了同样的行为,所以我将其称为 .NET (1.1) 错误是错误的。

我将在下面留下原始问题,但我修改后的问题是:如何让 Visual Studio 为我提供异常的堆栈跟踪信息,我已在“调用堆栈”窗口中捕获并重新抛出 ,而不是仅显示从 throw 语句开始的调用堆栈?

情况是我在运行时决定全局异常处理程序是打开还是关闭——如果关闭,我希望 VS 捕获异常,这样我就可以单步执行调用堆栈以找出问题所在。

以前,全局异常处理程序要么被编译到程序中,要么没有被编译到程序中。但是情况发生了变化,现在我们需要在运行时做出决定——看起来我可能需要回到宏观的方式来做这件事,但没有宏:

if (allow_bubble_up)
{
Foo();
}
else
{
try
{
Foo();
}
catch (Exception e)
{
GlobalExceptionHandler(e);
}
}

但对我来说,这种方法极度反对 DRY。


显然 .NET 1.1 中存在一个错误,如果您有一个空的 throw 语句来重新抛出捕获的异常,则堆栈跟踪将从 throw 的位置开始> 发生了,而不是重新抛出整个异常的堆栈跟踪——至少,我在几个博客上看到它被称为一个错误,但我还没有得到更多关于它的信息。

更具体一点,QuickWatch中$exceptionStackTrace属性显示了正确的数据,但是VS中的Call Stack窗口只显示调用堆栈到throw 语句的级别。

在此示例代码中,我只能看到 Main 的 1 级深度堆栈跟踪,即使我应该看到几个调用的堆栈跟踪Foo.

static public void Foo(int i)
{
if (i > 4)
{
throw new ArgumentOutOfRangeException();
}
Foo(i + 1);
}

static void Main(string[] args)
{
bool allow_bubble_up = true;
try
{
Foo(0);
}
catch (Exception e)
{
if (allow_bubble_up)
{
// stack trace just shows Main
throw;

// also just shows Main
//throw new Exception("asdf", e);

// STILL just shows Main
//throw e;
}
else
{
System.Console.WriteLine(e);
}
}
}

Fabrice Marguerie's blog展示了如何解决 .NET 2.0+ 的某种类型的重新抛出的堆栈跟踪,在底部他说查看 Chris Taylor 的博客以了解如何在 .NET 1.1 中执行此操作。我不得不搜索一下 find it on archive.org .我认为我正确地实现了它,但我仍然在 main 处得到堆栈跟踪——他的解释不是很清楚,我不想弄乱代码库(包装现有集其他方法中的功能)超出必要。

我可以在捕获和重新引发的异常的属性中看到正确的堆栈跟踪,但 VS 显示的可导航堆栈跟踪是无用的,因为它仅跟踪 throw 语句。如果我从未捕获并重新抛出异常,我获得完整且正确的堆栈跟踪。

如何在 VS 中显示正确的堆栈跟踪?我希望有某种简单的解决方法,但我一直在搜索错误的术语。

不幸的是,它必须是 VS2003+C#。

如果不清楚,这里是截图(您可能需要右键单击并查看图像):

alt text http://img257.imageshack.us/img257/1124/40727627.png

最佳答案

Visual Studio 将显示其停止处的调用堆栈。

在发生未处理 异常的情况下,它会在抛出该异常的地方停止。即你的“抛出”声明。但是,如果您的代码处理了异常,则 Visual Studio 会假设您知道自己在做什么,并忽略异常。它只会在 Main() 中重新抛出异常时捕获异常,因为您没有在程序中处理它。

如果你想在 visual studio 中捕获原始异常,你有两个选择:

  • 不要在代码中捕获异常。默认情况下,Visual Studio 只会在出现未处理 异常时停止。这当然意味着您的程序不会在运行时处理异常,因此这不是一个非常有用的方法!

  • 使用您的代码捕获并重新抛出异常(正如您正在做的那样),但将 Visual Studio 配置为在首次抛出内部异常时停止。转到 Debug>Exceptions 并勾选“公共(public)语言运行时”异常框(以停止任何异常)或浏览子树以启用特定异常的异常捕获(提示:如果您知道异常名称,请点击 Find... 按钮并输入名称的一部分,例如“FileNotFound”,以快速找到异常)。这将使 VS 停止在内部异常处,并且仅当您在检查异常详细信息后选择继续执行时才继续执行您的 catch{} 语句。

关于c# - 显示重新抛出的异常的堆栈跟踪,而不是从抛出点开始的堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1364082/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com