.net - StackTrace 中的托管/ native 转换在哪里?

标签 .net stack-trace

在 .NET 应用程序中,您可以从 Exception 对象获取堆栈跟踪。我正在该堆栈跟踪中寻找托管到 native 的转换(以及其他方向)。 Visual Studio 调试器可以显示这些特殊的帧,但在代码中,我看到了其他东西。有些帧没有托管 IL 偏移量(来自 GetILOffset() 方法),但具有 Visual Studio 看不到的模块和方法名称。它们从哪里来,我该如何解释它们?

以下屏幕截图显示了我的应用程序中此类堆栈跟踪的示例。黄色突出显示的是 Visual Studio 指示 native 方法的方法。元数据标记“+number”是托管 IL 代码偏移量。哪里没有,我怀疑是原生方法。

enter image description here

这是 Visual Studio 在同一位置显示的内容:

enter image description here

最佳答案

您将看到堆栈跟踪的两个不同 View ,否则无法使它们相同。干扰 View 的是 native 代码堆栈帧,可靠地行走 native 代码帧需要调试信息,需要 PDB 文件的那种,只有 native 调试器才有机会。

顶 View 由 StackTrace 对象生成。它完全跳过 native 堆栈帧。您突出显示的实际上是 C# 方法,它们具有 extern 属性。分别针对 [DllImport] 声明 (pinvoke) 和 [MethodImpl(MethodImplOptions.InternalCall)] (位于 CLR 内部且抖动了解的代码)。它们没有 IL,因此预计会从 GetILOffset() 获取 0。然而,这并不意味着 0 是可靠的指示,您必须重新找到该属性来过滤它们。

调试器的“调用堆栈”窗口有意隐藏这些方法。调试器无法显示任何对它们有意义的内容,在“自动”和“本地”窗口中无法显示任何内容。您必须启用非托管调试才能看到更多信息。

调试器 View 中的 [transition] 注释是根据抖动元数据生成的,这些信息只能通过调试器接口(interface)获得,而 StackTrace 类不会考虑这些信息。元数据是从托管堆栈帧之间的链接生成的,GC 需要这些元数据可靠地遍历堆栈帧,而不会出现误入非托管堆栈帧并将 native 指针值错误解释为对象引用的风险。这就是从托管代码转换到 native 代码并返回的含义,成本是维护这些链接。非常便宜。

关于.net - StackTrace 中的托管/ native 转换在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29260494/

相关文章:

c# - 找不到类型或命名空间名称...

c# - 如何观察DbSet<T>的Add Action ?

c# - 抛出异常时从堆栈跟踪和帧中获取文件名

debugging - 带有变量的haskell中调用堆栈的跟踪

compiler-optimization - 兄弟调用不会出现在堆栈跟踪中?

c# - 在 C# 程序集中的何处存储敏感数据?

.net - 在运行时将 WCF 服务绑定(bind)更改为 https

c# - 如何在 Xamarin Forms 中点击 ViewCell 后刷新 TableView 数据?

java - Android 手机不转储堆栈跟踪

java - Linux:Java Web 应用程序内存不足,不响应请求但不抛出 OOM?