使用sos的dump***命令查看一些东西

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用sos的dump***命令查看一些东西相关的知识,希望对你有一定的参考价值。

刚开始使用sos调试.net生成的程序,对里面的命令脑子中还是一片浆糊,这里只是写下自己所想而已,有错误不足之处,拜请高手指教:

首先说一下我对.net内存中存在的理解:

    所有的应用程序生成后是在一个进程中,这个进程是建立在4G大小的虚拟(我也不知道该叫逻辑内存还是虚拟内存)内存上(对32位机器)。换句话说,编译好的程序中的所有变量地址、方法地址指的都是这个虚拟内存中的地址。当程序在运行时也是使用的虚拟内存的地址来访问数据,但是操作系统会把虚拟内存地址通过某种技术映射到物理内存上,这样,程序就可以正常使用物理内存上的数据了。

    对于线程thread,我个人感觉只是一个运行概念上的东西,我考虑是一个线程对应一个指令指针(IP),多个线程只是说程序有多个(不止一个)IP指针,可以同时(这里的同时,是考虑到计算机运行速度是人难以察觉的同时,而不是严格意义上的同时,当然对于多处理器机器另当别论)执行不同的程序。所以我认为线程在内存空间上是没有明显隔离的,不能说给线程分配内存空间,从这个意义上讲和进程、线程对内存的分割占据不是一个概念。

    对于什么是句柄,本人还在学习中。。。

    在clr中,这样一个4G的虚拟内存又被隔离为多个AppDomain,AppDomain才是我们存放程序的基本单元空间。这里存放1个或多个assembly。


 

查看反汇编代码的sos指令路径:

process1  !dumpdomain  *domain1  !dumpdomain  *assembly1  !dumpassembly  *module1  !dumpmodule  *MethodTable1  !dumpmt  1MethodDescription1  !dumpmd   1CodeAddress1  !u  可以看到反汇编代码

 

 


指令解释:

(都是使用命令 !help [CommandName] 命令查看帮助所得)(红色部分是我理解不了的,请高手指教

0:009> !help dumpdomain
-------------------------------------------------------------------------------
!DumpDomain [<Domain address>]

When called with no parameters, !DumpDomain will list all the AppDomains in the process. It enumerates each Assembly loaded into those AppDomains as well. In addition to your application domain, and any domains it might create, there are two special domains: the Shared Domain and the System Domain.

Any Assembly pointer in the output can be passed to !DumpAssembly. Any Module pointer in the output can be passed to !DumpModule. Any AppDomain pointer can be passed to !DumpDomain to limit output only to that AppDomain. Other functions provide an AppDomain pointer as well, such as !Threads where it lists the current AppDomain for each thread.

 

0:009> !help dumpassembly
-------------------------------------------------------------------------------
!DumpAssembly <Assembly address>

Example output:

0:000> !dumpassembly 1ca248
Parent Domain: 0014f000
Name: C:\pub\unittest.exe
ClassLoader: 001ca060
Module Name
001caa50 C:\pub\unittest.exe

An assembly can consist of multiple modules, and those will be listed. You can get an Assembly address from the output of !DumpDomain.

 

0:009> !help dumpmodule
-------------------------------------------------------------------------------
!DumpModule [-mt] <Module address>

You can get a Module address from !DumpDomain, !DumpAssembly and other functions. Here is sample output:

0:000> !DumpModule 1caa50
Name: C:\pub\unittest.exe
Attributes: PEFile
Assembly: 001ca248
LoaderHeap: 001cab3c
TypeDefToMethodTableMap: 03ec0010
TypeRefToMethodTableMap: 03ec0024
MethodDefToDescMap: 03ec0064
FieldDefToDescMap: 03ec00a4
MemberRefToDescMap: 03ec00e8
FileReferencesMap: 03ec0128
AssemblyReferencesMap: 03ec012c
MetaData start address: 00402230 (1888 bytes)

The Maps listed map metadata tokens to CLR data structures. Without going into too much detail, you can examine memory at those addresses to find the
appropriate structures. For example, the TypeDefToMethodTableMap above can be examined:

0:000> dd 3ec0010
03ec0010 00000000 00000000 0090320c 0090375c
03ec0020 009038ec ...

This means TypeDef token 2 maps to a MethodTable with the value 0090320c. You can run !DumpMT to verify that. The MethodDefToDescMap takes a MethodDef token and maps it to a MethodDesc, which can be passed to !DumpMD.

There is a new option "-mt", which will display the types defined in a module,and the types referenced by the module. For example:

0:000> !dumpmodule -mt 1aa580
Name: C:\pub\unittest.exe
...<etc>...
MetaData start address: 0040220c (1696 bytes)

Types defined in this module

MT TypeDef Name
--------------------------------------------------------------------------
030d115c 0x02000002 Funny
030d1228 0x02000003 Mainy

Types referenced in this module

MT TypeRef Name
--------------------------------------------------------------------------
030b6420 0x01000001 System.ValueType
030b5cb0 0x01000002 System.Object
030fceb4 0x01000003 System.Exception
0334e374 0x0100000c System.Console
03167a50 0x0100000e System.Runtime.InteropServices.GCHandle
0336a048 0x0100000f System.GC

 

0:009> !help dumpmt
-------------------------------------------------------------------------------
!DumpMT [-MD] <MethodTable address>

Examine a MethodTable. Each managed object has a MethodTable pointer at the start. If you pass the "-MD" flag, you‘ll also see a list of all the methods  defined on the object.

 

0:009> !help dumpmd
-------------------------------------------------------------------------------
!DumpMD <MethodDesc address>

This command lists information about a MethodDesc. You can use !IP2MD to turn a code address in a managed function into a MethodDesc:

0:000> !dumpmd 902f40
Method Name: Mainy.Main()
Class: 03ee1424
MethodTable: 009032d8
mdToken: 0600000d
Module: 001caa78
IsJitted: yes
CodeAddr: 03ef00b8

If IsJitted is "yes," you can run !U on the CodeAddr pointer to see a disassembly of the JITTED code. You can also call !DumpClass, !DumpMT, !DumpModule on the Class, MethodTable and Module fields above.

 

0:009> !help u
-------------------------------------------------------------------------------
!U [-gcinfo] [-ehinfo] [-n] <MethodDesc address> | <Code address>

Presents an annotated disassembly of a managed method when given a MethodDescpointer for the method, or a code address within the method body. unlike the debugger "U" function, the entire method from start to finish is printed,with annotations that convert metadata tokens to names.

<example output>
...
03ef015d b901000000 mov ecx,0x1
03ef0162 ff156477a25b call dword ptr [mscorlib_dll+0x3c7764 (5ba27764)] (System.Console.InitializeStdOutError(Boolean), mdToken: 06000713)
03ef0168 a17c20a701 mov eax,[01a7207c] (Object: SyncTextWriter)
03ef016d 89442414 mov [esp+0x14],eax

If you pass the -gcinfo flag, you‘ll get inline display of the GCInfo for the method. You can also obtain this information with the !GCInfo command.

If you pass the -ehinfo flag, you‘ll get inline display of exception info for the method. (Beginning and end of try/finally/catch handlers, etc.).You can also  obtain this information with the !EHInfo command.

If the debugger has the option SYMOPT_LOAD_LINES specified (either by the.lines or .symopt commands), and if symbols are available for the managed module containing the method being examined, the output of the command will include the source file name and line number corresponding to the
disassembly. The -n (No line numbers) flag can be specified to disable this behavior.

<example output>
...
c:\Code\prj.mini\exc.cs @ 38:
001b00b0 8b0d3020ab03 mov ecx,dword ptr ds:[3AB2030h] ("Break in debugger. When done type <Enter> to continue: ")
001b00b6 e8d5355951 call mscorlib_ni+0x8b3690 (51743690) (System.Console.Write(System.String), mdToken: 0600091b)
001b00bb 90 nop

c:\Code\prj.mini\exc.cs @ 39:
001b00bc e863cdc651 call mscorlib_ni+0xf8ce24 (51e1ce24) (System.Console.ReadLine(), mdToken: 060008f6)
>>> 001b00c1 90 nop
...

 

以上是关于使用sos的dump***命令查看一些东西的主要内容,如果未能解决你的问题,请参考以下文章

Windbg SOS and CLR版本不一致的解决方案

Java命令学习系列——jhat

[转载] 从正在运行的Linux进程中dump出内存内容

linux 命令dump 备份的问题

内存dump文件导出与查看

Android dump命令查看某个apk是被谁安装的?