如何从SOS中的jitted输出获取托管函数名称?

时间:2021-10-19 16:00:20

I'm debugging the source code for mscorlib1 with WinDbg/SOS. I'm curious, is it possible to get the managed function name if you see its address in assembly? For example, this is some of the code I'm seeing in the disassembly window:

我正在使用WinDbg / SOS调试mscorlib1的源代码。我很好奇,如果你在汇编中看到它的地址,是否可以获得托管函数名称?例如,这是我在反汇编窗口中看到的一些代码:

00007ffd`7f035d7c 488d0d3d3af5ff  lea     rcx,[System_Private_CoreLib_ni+0x8797c0 (00007ffd`7ef897c0)]
00007ffd`7f035d83 e890728eff      call    System_Private_CoreLib_ni+0x20d018 (00007ffd`7e91d018)
00007ffd`7f035d88 488bf0          mov     rsi,rax
00007ffd`7f035d8b b9874a0000      mov     ecx,4A87h
00007ffd`7f035d90 e8834a91ff      call    System_Private_CoreLib_ni+0x23a818 (00007ffd`7e94a818)
00007ffd`7f035d95 488bc8          mov     rcx,rax
00007ffd`7f035d98 e87356b9ff      call    System_Private_CoreLib_ni+0x4bb410 (00007ffd`7ebcb410)
00007ffd`7f035d9d 488bd0          mov     rdx,rax
00007ffd`7f035da0 488bce          mov     rcx,rsi
00007ffd`7f035da3 e8e89fbdff      call    System_Private_CoreLib_ni+0x4ffd90 (00007ffd`7ec0fd90)

I want to find out what the names of some of these functions being call-ed are. I figure the command to use for this would be !dumpmd, but none of these commands seem to work:

我想知道被调用的一些函数的名称是什么。我认为用于此的命令将是!dumpmd,但这些命令似乎都不起作用:

!dumpmd 0x20d018
!dumpmd e890728eff
!dumpmd 00007ffd`7e91d018

All of them respond with "... is not a MethodDesc". How then can I get the managed function name from the assembly, or is it not possible?

所有人都回答“......不是MethodDesc”。那么如何才能从程序集中获取托管函数名称,或者它不可能?

1 mscorlib was recently renamed System.Private.CoreLib for .NET Core, so that's why you see that instead of mscorlib_ni.

1 mscorlib最近被重命名为.NET Core的System.Private.CoreLib,所以这就是为什么你看到它而不是mscorlib_ni。

2 个解决方案

#1


2  

!dumpmd 0x20d018

can't work, because you only pass the offset relative to the module. Without specifying the module (System_Private_CoreLib_ni), !dumpmd cannot know what you're referring to.

无法工作,因为您只传递相对于模块的偏移量。如果没有指定模块(System_Private_CoreLib_ni),!dumpmd就无法知道你所指的是什么。

!dumpmt e890728eff

can't work, because you pass machine code to !dumpmt. e8 is the machine code for the assembly instruction call and the rest is a relative offset. To interpret that, !dumpmt would need to know the address of the instruction so that it can calculate the address of the method being called.

无法工作,因为您将机器代码传递给!dumpmt。 e8是汇编指令调用的机器代码,其余是相对偏移量。要解释它,!dumpmt需要知道指令的地址,以便它可以计算被调用方法的地址。

!dumpmt 00007ffd`7e91d018

could at least be plausible, because you pass an absolute address. That is a meaningful address. But it's not the address of a method table which !dumpmt expects.

至少可能是合理的,因为你传递了一个绝对的地址。这是一个有意义的地址。但它不是!dumpmt所期望的方法表的地址。

With a given native address, you can use

使用给定的本地地址,您可以使用

!IP2MD <Code address> Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.

!IP2MD <代码地址> 在已编译JIT的代码中的指定地址处显示MethodDesc结构。

Actually the command will display much more, including the method name.

实际上该命令将显示更多,包括方法名称。

0:000> !ip2md 001fce80
MethodDesc:   00508ab4
Method Name:  ReporterCmd.Program+<>c..cctor()
Class:        0025e10c
MethodTable:  00508ad0
mdToken:      06000027
Module:       00193fbc
IsJitted:     yes
CodeAddr:     001fce48
Transparency: Critical

The (download) command !mln as implemented by @Steve Johnson and mentioned in his answer is really helpful, since it will auto detect the nearest useful thing, so you needn't know in detail what you have.

由@Steve Johnson实现并在他的回答中提到的sosex(下载)命令!mln非常有用,因为它会自动检测最近的有用信息,所以你不需要详细了解你拥有的内容。

0:000> !mln 001fce80
Method instance: (BEGIN=001fce48)(MD=00508ab4 disassemble)[ReporterCmd.Program+<>c..cctor()]

If you're learning about .NET internals, I recommend using !mln and then finding out how to get the same results using other methods so that you know about the relationship of things.

如果您正在学习.NET内部,我建议使用!mln然后找出如何使用其他方法获得相同的结果,以便您了解事物的关系。

#2


2  

Pass the entire address to !sosex.mln

将整个地址传递给!sosex.mln

#1


2  

!dumpmd 0x20d018

can't work, because you only pass the offset relative to the module. Without specifying the module (System_Private_CoreLib_ni), !dumpmd cannot know what you're referring to.

无法工作,因为您只传递相对于模块的偏移量。如果没有指定模块(System_Private_CoreLib_ni),!dumpmd就无法知道你所指的是什么。

!dumpmt e890728eff

can't work, because you pass machine code to !dumpmt. e8 is the machine code for the assembly instruction call and the rest is a relative offset. To interpret that, !dumpmt would need to know the address of the instruction so that it can calculate the address of the method being called.

无法工作,因为您将机器代码传递给!dumpmt。 e8是汇编指令调用的机器代码,其余是相对偏移量。要解释它,!dumpmt需要知道指令的地址,以便它可以计算被调用方法的地址。

!dumpmt 00007ffd`7e91d018

could at least be plausible, because you pass an absolute address. That is a meaningful address. But it's not the address of a method table which !dumpmt expects.

至少可能是合理的,因为你传递了一个绝对的地址。这是一个有意义的地址。但它不是!dumpmt所期望的方法表的地址。

With a given native address, you can use

使用给定的本地地址,您可以使用

!IP2MD <Code address> Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.

!IP2MD <代码地址> 在已编译JIT的代码中的指定地址处显示MethodDesc结构。

Actually the command will display much more, including the method name.

实际上该命令将显示更多,包括方法名称。

0:000> !ip2md 001fce80
MethodDesc:   00508ab4
Method Name:  ReporterCmd.Program+<>c..cctor()
Class:        0025e10c
MethodTable:  00508ad0
mdToken:      06000027
Module:       00193fbc
IsJitted:     yes
CodeAddr:     001fce48
Transparency: Critical

The (download) command !mln as implemented by @Steve Johnson and mentioned in his answer is really helpful, since it will auto detect the nearest useful thing, so you needn't know in detail what you have.

由@Steve Johnson实现并在他的回答中提到的sosex(下载)命令!mln非常有用,因为它会自动检测最近的有用信息,所以你不需要详细了解你拥有的内容。

0:000> !mln 001fce80
Method instance: (BEGIN=001fce48)(MD=00508ab4 disassemble)[ReporterCmd.Program+<>c..cctor()]

If you're learning about .NET internals, I recommend using !mln and then finding out how to get the same results using other methods so that you know about the relationship of things.

如果您正在学习.NET内部,我建议使用!mln然后找出如何使用其他方法获得相同的结果,以便您了解事物的关系。

#2


2  

Pass the entire address to !sosex.mln

将整个地址传递给!sosex.mln