如何判断函数是否是托管代码?

对于纯C#应用来说,这是一个没有实际意义的问题,但是如果你用MC++(或其他一些“混合”语言)编写,并且你想知道一个函数是被编译成托管代码还是本机代码呢?
您可以尝试检查源代码并根据语言规则进行推断。例如,在MC++中,查找#pragma managed/#pragma unmanaged。然而,这是有风险的,因为可能有一些你不知道的语言规则。(小测验:你知道MC++将函数编译成本机代码而不是IL的所有规则吗?)

所以如果你想要更多偏执的验证。。。

  • 使用ILDasm查看函数是否实际为IL。
  • 如果它在仅托管调试时出现,则它是托管代码。所以请检查您是否正在进行互操作调试,如果不是,您看到的任何内容都是托管的。
  • 在调用堆栈上查找托管2本机标记。
  • 如果调试时实际在函数中停止,请查看反汇编。

VS显示从偏移量0开始的托管调试反汇编,例如:

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");
00000000  push        edi  
00000001  push        esi  
00000002  push        ebx  

而本机反汇编以绝对地址显示:

 int Add(int a, int b)
{
00401000  push        ebp  
00401001  mov         ebp,esp 
    return a + b;
00401003  mov         eax,dword ptr [a] 
00401006  add         eax,dword ptr [b] 
}

这显然是一种启发,因为它只是VS的行为特定方面。CLR调试服务提供jitted代码的实际地址,因此VS可以同时显示manage和native反汇编。然而,stackwalking api 100%清楚地知道代码是托管的还是本机的,因此调试器工具也可以将这些信息传递给用户。

 

posted on 2020-12-04 08:04  活着的虫子  阅读(182)  评论(0编辑  收藏  举报

导航