记一次.net异常代码位置定位

  • 今天公司的技术支持在现场发了一张软件异常的图片给我,如下图

  • 从日志图形界面看出,只有一个索引超出数组范围的错误信息,判定不了出错的代码位置在哪里,于是又让他去日志文件把错误日志摘出来,如下所示

    2025-04-18 11:00:00:740 XXXX.XXXX.XXXX lineNo:128 Index was outside the bounds of the array.
    
  • 既然日志文件里已经记录了代码的行数,我就简单的认为这个问题很快就能被定位,于是迅速打开vs,定位到 128 行,有些傻眼了,简化下大致是如下代码(fake)

    RunService service = new RunService();
    try
    {
        service.Init();
        service.Run();
        service.Dispose();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex.Message); // 日志文件中记录的128行是这行代码 之所以不打印堆栈,是因为和用户界面相关联,不适合将堆栈信息暴露给用户看。
    }
    
  • 目前只能定位到该方法,无法进一步确认具体报错的代码位置,由于又是生产环境,所以没有vs和源代码可供调试,这就让人头疼了。

  • 突然想起来之前学windbg的时候,有一节是讲用 dnSpy 调试 .net 程序的,所以打算用 dnSpy 试试

    • 为什么不用windbg,而是尝试使用dnspy:windbg安装巨慢,加载symbol也巨慢,有时候还安装不成功,dnspy小巧便捷

dnSpy调试定位错误

  • 将程序入口dll和报错方法所在的dll拖入到 dnSpy 中(我这里演示的只有一个dll)

  • 先找到反编译后的方法,打上断点 然后选中入口dll,点击运行

  • 命中断点后查看异常信息

    • 这里的 StackTrace 不能点开看,只能右键 复制值 粘贴到其他地方查看,文本如下所示

      "   at DebugSamples.RunService.Run() in D:\\files\\blend\\git pros\\gitee\\blog-codes\\dotnet\\DebugSamples\\DebugSamples\\RunService.cs:line 7\r\n   at DebugSamples.MainWindow.TestBtn_Click(Object sender, RoutedEventArgs e) in D:\\files\\blend\\git pros\\gitee\\blog-codes\\dotnet\\DebugSamples\\DebugSamples\\MainWindow.xaml.cs:line 20"
      
      • 可以看到具体的报错位置是 RunService.cs 的第7行
  • 当然,以上只是一个简单的示例,实际情况将更加复杂,特别是混淆+async/await 后的代码,可读性非常差,不容易找到打印日志的地方,这个就需要耐着性子去找了。

  • 除了以上方法,如果你知道报错的异常类型可以通过异常设置快速定位(和vs简直一模一样),看下图所示,就不详细描述了。

添加所有异常记录

  • 定位完这个问题后,就想着如何将程序的所有异常都记录在文件中(而不是界面上),问完GPT之后还真有个简单粗暴的方式
    • AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
  • 当然,要把这个功能做成可选项,毕竟捕获所有的异常对性能有所影响。

perfview监控所有进程的异常

  • 尝试了一下,确实可以,但是非常卡顿(不管是收集还是读取都卡),如果后续有需求再单独记录一下perfview的用法
posted on 2025-04-18 20:13  baby-jie  阅读(29)  评论(0)    收藏  举报