C# 关于CLR,本机调用堆栈究竟是什么?

C# 关于CLR,本机调用堆栈究竟是什么?,c#,clr,C#,Clr,浏览我遇到的某个论坛,回答者将以下内容称为本机调用堆栈 00000000`0014ea10 00000642`7f67d4a2 0x642`80150142 00000000`0014ea90 00000642`7f5108f5 mscorwks!CallDescrWorker+0x82 00000000`0014eae0 00000642`7f522ff6 mscorwks!CallDescrWorkerWithHandler+0xe5 00000000`0014eb80 00000642`

浏览我遇到的某个论坛,回答者将以下内容称为本机调用堆栈

00000000`0014ea10 00000642`7f67d4a2 0x642`80150142
00000000`0014ea90 00000642`7f5108f5 mscorwks!CallDescrWorker+0x82 
00000000`0014eae0 00000642`7f522ff6 mscorwks!CallDescrWorkerWithHandler+0xe5
00000000`0014eb80 00000642`7f49a94b mscorwks!MethodDesc::CallDescr+0x306 
00000000`0014edb0 00000642`7f474ae4 mscorwks!ClassLoader::RunMain+0x23f
00000000`0014f010 00000642`7f5efb1a mscorwks!Assembly::ExecuteMainMethod+0xbc 
00000000`0014f300 00000642`7f467d97 mscorwks!SystemDomain::ExecuteMainMethod+0x492
00000000`0014f8d0 00000642`7f482c24 mscorwks!ExecuteEXE+0x47
关于CLR,本机调用堆栈到底是什么(这里我们看到的是调用我认为主要方法的CLR),我如何在本地机器上查看并理解所述本机调用堆栈,以便进行教学 与托管代码使用堆栈的方式相比,非托管代码使用堆栈的方式没有根本区别。唯一的区别是,您需要一个非托管调试器来实际查看堆栈跟踪中的非托管函数。托管调试器只报告堆栈跟踪中的[managed to Native Transition],并隐藏非托管函数

这是高效的,您通常对非托管代码一点也不感兴趣,并且很可能缺少使跟踪准确所需的PDB。对于CLR,需要启用Microsoft Symbol服务器。托管堆栈跟踪始终是准确的,CLR提供了堆栈遍历可以正常工作的硬保证,因为垃圾收集器和CA需要执行堆栈遍历以完成其工作。由于C++代码生成器中的优化,非托管堆栈跟踪更加困难,例如,帧指针省略优化对堆栈行走是非常致命的。 你当然可以看到两者。项目+属性,调试选项卡,勾选“启用本机代码调试”选项。

“本机调用堆栈”表示通过非托管库的调用堆栈(部分)。由于操作系统不是托管的,所以托管堆栈总是有一些非托管入口点。但是,您也可以在它上面有非托管方法,即如果托管代码调用系统函数。调用堆栈可以包含任意数量的托管到本机和本机到托管的转换。要想看到合理的结果,应该启用“非托管调试”


在上面的示例中,可以看到源自mscorwks.dll的调用,它是包含.NET执行引擎的主dll。由于该库的符号丢失(除非您下载了它们,请参见“Microsoft符号服务器”上的google),因此您只需要搜索不同函数的入口点。一行代码为
mscorwks!CallDescrWorkerWithHandler+0xe5
表示该调用源自mscorwks.dll中名为“CallDescrWorkerWithHandler”的函数,即该函数开头的0xe5字节

回答得太好了。非常感谢。