StackTrace 中的 managed/native 转换在哪里?
Where are managed/native transitions in the StackTrace?
在 .NET 应用程序中,您可以从 Exception
对象中获取堆栈跟踪。我正在该堆栈跟踪中寻找托管到本机的转换(和其他方向)。 Visual Studio 调试器可以显示这些特殊帧,但在代码中,我看到了其他东西。有些框架没有托管 IL 偏移量(来自 GetILOffset()
方法),但具有 Visual Studio 看不到的模块和方法名称。它们来自哪里,我该如何解读它们?
以下屏幕截图显示了我的应用程序中此类堆栈跟踪的示例。黄色突出显示的是 Visual Studio 表示本机方法的方法。元数据标记“+number”是托管 IL 代码偏移量。 none在哪里,我怀疑是native方法
这是 Visual Studio 为同一地点显示的内容:
您看到了堆栈跟踪的两个不同视图,否则无法使它们相同。扰乱视图的是本机代码堆栈帧,可靠地运行本机代码帧需要调试信息,需要 PDB 文件的那种,只有本机调试器才能做到。
顶部视图由 StackTrace 对象生成。它完全跳过本机堆栈帧。您突出显示的实际上是 C# 方法,它们具有 extern
属性。分别针对 [DllImport]
声明 (pinvoke) 和 [MethodImpl(MethodImplOptions.InternalCall)]
(位于 CLR 内部的代码和抖动知道的代码)。它们没有 IL,因此预计会从 GetILOffset() 获得 0。然而,这并不意味着 0 是可靠的指示,您必须找到属性以过滤它们。
调试器的调用堆栈window 有意隐藏了这些方法。调试器不能显示任何对他们有意义的东西,在自动和局部变量中没有任何东西可以显示 window。您必须启用非托管调试才能看到更多信息。
调试器视图中的 [transition] 注释是从抖动元数据生成的,这些信息只能通过调试器界面获得,StackTrace 不会考虑 class。从托管堆栈帧之间的链接生成元数据,GC 需要这些元数据可靠地遍历堆栈帧,而不会有误入非托管堆栈帧和将本机指针值错误解释为对象引用的风险。这就是从托管代码转换到本机代码并返回的意思,成本是维护这些链接。很便宜。
在 .NET 应用程序中,您可以从 Exception
对象中获取堆栈跟踪。我正在该堆栈跟踪中寻找托管到本机的转换(和其他方向)。 Visual Studio 调试器可以显示这些特殊帧,但在代码中,我看到了其他东西。有些框架没有托管 IL 偏移量(来自 GetILOffset()
方法),但具有 Visual Studio 看不到的模块和方法名称。它们来自哪里,我该如何解读它们?
以下屏幕截图显示了我的应用程序中此类堆栈跟踪的示例。黄色突出显示的是 Visual Studio 表示本机方法的方法。元数据标记“+number”是托管 IL 代码偏移量。 none在哪里,我怀疑是native方法
这是 Visual Studio 为同一地点显示的内容:
您看到了堆栈跟踪的两个不同视图,否则无法使它们相同。扰乱视图的是本机代码堆栈帧,可靠地运行本机代码帧需要调试信息,需要 PDB 文件的那种,只有本机调试器才能做到。
顶部视图由 StackTrace 对象生成。它完全跳过本机堆栈帧。您突出显示的实际上是 C# 方法,它们具有 extern
属性。分别针对 [DllImport]
声明 (pinvoke) 和 [MethodImpl(MethodImplOptions.InternalCall)]
(位于 CLR 内部的代码和抖动知道的代码)。它们没有 IL,因此预计会从 GetILOffset() 获得 0。然而,这并不意味着 0 是可靠的指示,您必须找到属性以过滤它们。
调试器的调用堆栈window 有意隐藏了这些方法。调试器不能显示任何对他们有意义的东西,在自动和局部变量中没有任何东西可以显示 window。您必须启用非托管调试才能看到更多信息。
调试器视图中的 [transition] 注释是从抖动元数据生成的,这些信息只能通过调试器界面获得,StackTrace 不会考虑 class。从托管堆栈帧之间的链接生成元数据,GC 需要这些元数据可靠地遍历堆栈帧,而不会有误入非托管堆栈帧和将本机指针值错误解释为对象引用的风险。这就是从托管代码转换到本机代码并返回的意思,成本是维护这些链接。很便宜。