如何判断函数是否是托管代码?
对于纯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%清楚地知道代码是托管的还是本机的,因此调试器工具也可以将这些信息传递给用户。
为虫子生,为虫子死,为虫子奋斗一辈子