异常调用堆栈被截断,没有任何重新抛出

2024-02-16

我有一个不寻常的情况,我有一个非常简单的异常被抛出并在同一方法中捕获。它不会被重新抛出(天真的程序员通常会遇到这样的问题)。然而它的 StackFrame 只包含一个当前方法。它看起来是这样的:

   at (my class).MyMethod() in C:\(my file path and line)

实际上,VS2010 调试器的调用堆栈中可能有 30 个方法导致此情况,涉及六个不同的程序集。所有这些似乎不可能被优化掉。此外,这段代码是内置的调试模式,无优化,对于.NET 4。我什至有(基于http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini 文件(包括名为 [app].vshost.ini 的文件)位于同一文件夹中,其中包含:

[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0

此外,方法调用不在方法的末尾,因此尾递归优化似乎更不可能。

至于它是如何调用的:调用堆栈上没有使用反射,没有任何类型的 Invoke() 或 BeginInvoke()。这只是通过单击按钮产生的一长串调用。单击处理程序位于调用堆栈中大约 10 个调用处。在其下面有常见的 WndProc、NativeWindow.Callback、本机/托管转换和消息循环。这最终是在从 C# EXE 程序集运行的 ShowDialog() 调用中进行的。

现在,我发现我可以在 catch 处理程序中构造 StackTrace 类的实例,并且如果我传递 Exception 对象,调用堆栈也会很短。相反,如果我只调用不带参数的 new StackTrace(),它会生成完整的调用堆栈。

我尝试使用 Reflector 来调试抛出的 Exception 类的内部结构及其构造的调用堆栈,但我无法在 Exception 或 StackTrace 中设置断点。我可以在 Environment.GetStackTrace() 中设置它们,并且这个方法(Exception 调用的)在构造和抛出过程中似乎不会被调用,但我不知道调试器是否真的正常工作。 (这个方法确实会被其他一些事情触发,所以我不知道该怎么做。)

以下是该方法的摘录:

private void MyMethod()
{
    ...               
    try
    {
        throw new ApplicationException("Test failure");
    }
    catch (Exception e)
    {
        StackTrace stackTrace1 = new StackTrace(e);
        StackTrace stackTrace2 = new StackTrace(e, false);
        StackTrace stackTrace3 = new StackTrace(e, true);
        StackTrace stackTrace4 = new StackTrace();
        string STs = stackTrace1.ToString() + "\n---\n"
            + stackTrace2.ToString() + "\n---\n"
            + stackTrace3.ToString() + "\n---\n"
            + stackTrace4.ToString();
        Log(EventSeverity.Debug, STs);
        ...
        }
    }

这真的非常简单:抛出异常,捕获并记录它。

无论是在调试器中还是在独立运行(单行调用堆栈)时,我都会得到相同的结果。我知道我在我们的代码库的其他地方看到过这个问题。以前我认为这是由于重新抛出异常,但在很多情况下,我们直接在初始 catch 块内记录。我很困惑,我所做的所有网络搜索都没有产生任何结果。


作为对所提供答案的评论添加有点太多了,但这里有更多信息:

我现在看到这种行为正在讨论http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/ http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/它实际上是在http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx(尽管我认为人们很容易错过他们在那里所说的内容)。

所以我想我的“解决方案”会有点碰运气。我们有一个通常调用来格式化异常的中心方法。在该方法中,我将创建一个带有或不带有 Exception 对象的新 StackTrace()。然后,我将查找异常堆栈跟踪底部的方法,并在 new StackTrace() 中显示该方法下方的所有内容,表明该方法是由该系列调用调用的。

当然,缺点是如果不使用此方法,则信息将不存在。但我不得不期待某些地方会发生某种代码更改。


当抛出异常时,将仅使用部分堆栈跟踪Exception.StackTrace财产。堆栈仅显示捕获异常的方法之前的调用。要获得完整的堆栈(正如您所指出的),您应该创建一个new StackTrace() object.

我目前找不到任何链接,但我相信堆栈跟踪是通过在抛出异常时向上遍历堆栈来构建的。一旦异常到达 catch 块,堆栈就会停止编译。因此,您只能得到部分堆栈。

通常,catch 块不关心谁调用它,而是关心异常源自何处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异常调用堆栈被截断,没有任何重新抛出 的相关文章

  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 有什么工具可以说明每种方法运行需要多长时间?

    我的程序的某些部分速度很慢 我想知道是否有我可以使用的工具 例如它可以告诉我可以运行 methodA 花了 100ms 等等 或者类似的有用信息 如果您使用的是 Visual Studio Team System 性能工具 中有一个内置分析
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • std::bind 重载解析

    下面的代码工作正常 include
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 哪些属性有助于运行时 .Net 性能?

    我正在寻找可用于通过向加载器 JIT 编译器或 ngen 提供提示来确保 Net 应用程序获得最佳运行时性能的属性 例如我们有可调试属性 http msdn microsoft com en us library k2wxda47 aspx
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 如何在 GCC 5 中处理双 ABI?

    我尝试了解如何克服 GCC 5 中引入的双重 ABI 的问题 但是 我没能做到 这是一个重现错误的非常简单的示例 我使用的GCC版本是5 2 如您所见 我的主要函数 在 main cpp 文件中 非常简单 main cpp include
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使

随机推荐