如何从 SOS 的 jitted 输出中获取托管函数名称?
How to get the managed function name from the jitted output in SOS?
我正在使用 WinDbg/SOS 调试 mscorlib1 的源代码。我很好奇,如果您在程序集中看到它的地址,是否可以获取托管函数名称?例如,这是我在反汇编 window:
中看到的一些代码
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)
我想知道其中一些被 call
编辑的函数的名称是什么。我认为用于此的命令是 !dumpmd
,但这些命令中的 none 似乎有效:
!dumpmd 0x20d018
!dumpmd e890728eff
!dumpmd 00007ffd`7e91d018
他们都回应“...不是 MethodDesc”。那么我怎样才能从程序集中获取托管函数名称,还是不可能?
1 mscorlib 最近被重命名为 System.Private.CoreLib
for .NET Core,所以这就是为什么你看到它而不是 mscorlib_ni
。
将整个地址传递给!sosex.mln
!dumpmd 0x20d018
不行,因为你只传递了相对于模块的偏移量。如果不指定模块 (System_Private_CoreLib_ni),!dumpmd
无法知道您指的是什么。
!dumpmt e890728eff
无法工作,因为您将机器代码传递给 !dumpmt
。 e8
是汇编指令call
的机器码,其余是相对偏移量。要解释它,!dumpmt
需要知道指令的地址,以便它可以计算被调用方法的地址。
!dumpmt 00007ffd`7e91d018
至少是合理的,因为你传递了一个绝对地址。这是一个有意义的地址。但这不是 !dumpmt
期望的方法 table 的地址。
使用给定的本机地址,您可以使用
!IP2MD <Code address> Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.
实际上命令会显示更多,包括方法名称。
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
sosex (download) command !mln
as implemented by @Steve Johnson and mentioned in 真的很有用,因为它会自动检测最近的有用的东西,所以你不需要详细知道你有什么。
0:000> !mln 001fce80
Method instance: (BEGIN=001fce48)(MD=00508ab4 disassemble)[ReporterCmd.Program+<>c..cctor()]
如果您正在学习 .NET 内部结构,我建议您使用 !mln
,然后了解如何使用其他方法获得相同的结果,以便您了解事物之间的关系。
我正在使用 WinDbg/SOS 调试 mscorlib1 的源代码。我很好奇,如果您在程序集中看到它的地址,是否可以获取托管函数名称?例如,这是我在反汇编 window:
中看到的一些代码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)
我想知道其中一些被 call
编辑的函数的名称是什么。我认为用于此的命令是 !dumpmd
,但这些命令中的 none 似乎有效:
!dumpmd 0x20d018
!dumpmd e890728eff
!dumpmd 00007ffd`7e91d018
他们都回应“...不是 MethodDesc”。那么我怎样才能从程序集中获取托管函数名称,还是不可能?
1 mscorlib 最近被重命名为 System.Private.CoreLib
for .NET Core,所以这就是为什么你看到它而不是 mscorlib_ni
。
将整个地址传递给!sosex.mln
!dumpmd 0x20d018
不行,因为你只传递了相对于模块的偏移量。如果不指定模块 (System_Private_CoreLib_ni),!dumpmd
无法知道您指的是什么。
!dumpmt e890728eff
无法工作,因为您将机器代码传递给 !dumpmt
。 e8
是汇编指令call
的机器码,其余是相对偏移量。要解释它,!dumpmt
需要知道指令的地址,以便它可以计算被调用方法的地址。
!dumpmt 00007ffd`7e91d018
至少是合理的,因为你传递了一个绝对地址。这是一个有意义的地址。但这不是 !dumpmt
期望的方法 table 的地址。
使用给定的本机地址,您可以使用
!IP2MD <Code address> Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.
实际上命令会显示更多,包括方法名称。
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
sosex (download) command !mln
as implemented by @Steve Johnson and mentioned in
0:000> !mln 001fce80
Method instance: (BEGIN=001fce48)(MD=00508ab4 disassemble)[ReporterCmd.Program+<>c..cctor()]
如果您正在学习 .NET 内部结构,我建议您使用 !mln
,然后了解如何使用其他方法获得相同的结果,以便您了解事物之间的关系。