gpt4 book ai didi

.net - 用于调试和发布构建的 WinDbg 不同堆栈跟踪

转载 作者:行者123 更新时间:2023-12-04 17:57:19 25 4
gpt4 key购买 nike

我根据 MSDN 正确设置了 Windbg .问题是,当我在 Debug模式下获得转储文件时,我可以正确地看到调用堆栈(正确加载符号)。

000000f758b6eac0 00007ffb5be60559 System.Number.StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean)
000000f758b6eb20 00007ffb5b0cd791 System.Number.ParseInt32(System.String, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo)
000000f758b6ec70 00007ffafcc60214 ConsoleApplication1.Program.ConvertToInt(System.String)
000000f758b6ecb0 00007ffafcc60105 ConsoleApplication1.Program.Main()
000000f758b6f030 00007ffb5c3b4113 [GCFrame: 000000f758b6f030]

当我在 Release模式下获取转储文件时,缺少一些信息,特别是在 Debug模式下可见的方法名称“ConvertToInt”。

00000081df98c710 00007ffafcc701e1 ConsoleApplication1.Program.Main() [C:\Written Programs\ConsoleApplication1\ConsoleApplication1\Program.cs @ 29]
00000081df98e6a8 00007ffb5c3eb915 [HelperMethodFrame: 00000081df98e6a8]
00000081df98e790 00007ffb5be60559 System.Number.StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean)
00000081df98e7f0 00007ffb5b0cd791 System.Number.ParseInt32(System.String, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo)
00000081df98e940 00007ffafcc700e0 ConsoleApplication1.Program.Main() [C:\Written Programs\ConsoleApplication1\ConsoleApplication1\Program.cs @ 23]

我是不是做错了什么?
加上 HelperMethodFrame 是什么意思?除了在 Debug模式下,即使没有程序 .pdb 文件,我仍然可以正确地看到调用堆栈。 .pdb 文件究竟是做什么用的。我已经阅读了定义和所有内容,只需要一个关于它如何与 Windbg 一起工作的实际答案?

最佳答案

这是完全正常的,您的 Release 构建程序启用了抖动优化器。阅读this answer对于它执行的优化类型。

您的 Program.ConvertToInt() 方法成为该列表中第一个项目符号的牺牲品。它得到了内联。内联是一种非常基本的优化策略,优化器不是发出 CALL 来调用方法,而是注入(inject)方法的代码。对于不会生成大量机器代码的小方法,它会发生。这是一个重要的优化,它可以避免必须设置调用堆栈和进行分支,它可以轻松地节省几纳秒。并使更多优化可用,包括但不限于在优化器可以确定特定参数使得运行代码不必要时使整个方法开销消失。

HelperMethodFrame 是一个深入的 CLR 实现细节,它出现在所谓的 FCall 调用 CLR 中的函数中。不设置自己的堆栈框架但搭载在程序的堆栈框架上的调用。 FCall == "fast call",心理图像是 C# 代码直接调用 native C++ 代码而没有任何互操作。但是当该函数确定无论如何都需要堆栈帧以正确发出异常时,它会动态构建一个。没有名称与之关联。 this blog post 中的 fcalls 背景有点不透明.

当然,这些类型的优化会使调试 Release 构建的代码变得非常复杂。这是 Debug 配置存在的核心原因,它禁用优化,因此程序更容易调试。您可以将 [MethodImpl(MethodImplOptions.NoInlining)] 属性应用于方法以防止它被内联。这不是你应该大量做的事情,因为它是性能 killer ,但对于这种代码来说是完全合理的,因为将字符串解析为数字无论如何都是昂贵的。

关于.net - 用于调试和发布构建的 WinDbg 不同堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24859025/

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