首先写一段代码如下:

namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, Windbg!"); Console.ReadKey();
}
}
}

  在Debug目录中启动该程序,然后在Debug中附加该进程。

0:007> .load C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/sos.dll
0:007> !dumpdomain
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll -
PDB symbol for clr.dll not loaded
--------------------------------------
System Domain: 7106e898
LowFrequencyHeap: 7106ebbc
HighFrequencyHeap: 7106ec04
StubHeap: 7106ec4c
Stage: OPEN
Name: None
--------------------------------------
Shared Domain: 7106e4f0
LowFrequencyHeap: 7106ebbc
HighFrequencyHeap: 7106ec04
StubHeap: 7106ec4c
Stage: OPEN
Name: None
Assembly: 0051a1b8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader: 00501660
Module Name
697e1000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll --------------------------------------
Domain 1: 004e78a8
LowFrequencyHeap: 004e7cfc
HighFrequencyHeap: 004e7d44
StubHeap: 004e7d8c
Stage: OPEN
SecurityDescriptor: 004e9388
Name: ConsoleApplication3.exe
Assembly: 0051a1b8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader: 00501660
SecurityDescriptor: 0051a130
Module Name
697e1000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Assembly: 00521db8 [C:\Users\ChenZhuo\Documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe]
ClassLoader: 005016c8
SecurityDescriptor: 00521d30
Module Name
00212eac C:\Users\ChenZhuo\Documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe

  从上面的输出结果中,有如下发现:

  1. .Net app默认情况下,会有三个AppDomain,其中分别是System Domain,Shared Domain和应用程序自己的Application Domain(就是上面的Domain1);
  2. 一个domain内包含一个或若干个Assembly;

如果仅仅只是想查看一个domain,则可以使用如下命令,其输出结果与上面的结果一致:

:> !dumpdomain 004e78a8
--------------------------------------
Domain : 004e78a8
LowFrequencyHeap: 004e7cfc
HighFrequencyHeap: 004e7d44
StubHeap: 004e7d8c
Stage: OPEN
SecurityDescriptor: 004e9388
Name: ConsoleApplication3.exe
Assembly: 0051a1b8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:
SecurityDescriptor: 0051a130
Module Name
697e1000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Assembly: 00521db8 [C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe]
ClassLoader: 005016c8
SecurityDescriptor: 00521d30
Module Name
00212eac C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe

  在上面的app domain中,我们可以看到包含了2个assembly,分别是mscorlib.dll和ConsoleApplication3.exe。

  都有1个module。这里我们看ConsoleApplication3.exe。

  看assembly信息,命令使用:!dumpassembly <assembly address>,我们执行:!dumpassembly <00212eac> 这个地址就在appdomain命令返回的程序集路径的左边。

:> !dumpassembly 00521db8
Parent Domain: 004e78a8
Name: C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
ClassLoader: 005016c8
Module Name
00212eac C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe

  注意:

  1. assembly包含了指向domain的信息,上面的004e78a8;
  2. assembly包含了一个或者若干个module;

  这里只有一个module,我们继续看module里面包含啥。

  命令!dumpmodule有一个有用的开关,是-mt <mt address>,我们跑一下看看:!dumpmodule -mt 1caa50

:> !dumpmodule -mt 00212eac
Name: C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
Attributes: PEFile
Assembly: 00521db8
LoaderHeap:
TypeDefToMethodTableMap:
TypeRefToMethodTableMap:
MethodDefToDescMap:
FieldDefToDescMap: 002100a4
MemberRefToDescMap: 002100a8
FileReferencesMap: 002100fc
AssemblyReferencesMap:
MetaData start address: 012a206c ( bytes) Types defined in this module MT TypeDef Name
------------------------------------------------------------------------------
002137c0 0x02000002 ConsoleApplication3.Program Types referenced in this module MT TypeRef Name
------------------------------------------------------------------------------
69bb25e8 0x02000001 System.Object
69bb869c 0x02000013 System.Console

  我们能发现两个重要的东西:

  1. 这个module里面包含的types,这里是我们的程序主入口点:ConsoleApplication3.Program;
  2. 这个module引用的types,这里是object和Console;

  看上面的ConsoleApplication3.Program,这个type对应的MethodTable地址是:002137c0。我们可以继续看这个MethodTable包含啥东西:

:> !dumpmt 00212eac
00212eac is not a MethodTable
:> !dumpmt 002137c0
EEClass: 0021125c
Module: 00212eac
Name: ConsoleApplication3.Program
mdToken:
File: C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable:
Number of IFaces in IFaceMap:

  这里有一些重要的东西可以看:

  1. EEClass,可以通过!dumpclass <class address>来查看这个class的信息。如:!dumpclass 0021125c;
  2. 包含了Module和name等信息;
  3. 包含了Method Description 信息;
  4. VTable里面的slots一共6个;

  MethodTable只是一个入口表,它实际指向了一堆Method Description,那么我们可以用!dumpmt继续来查看,只不过参数要修改一下:!dumpmt -md 002137c0

:> !dumpmt 002137c0
EEClass: 0021125c
Module: 00212eac
Name: ConsoleApplication3.Program
mdToken:
File: C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable:
Number of IFaces in IFaceMap:
:> !dumpmt -md 00212eac
00212eac is not a MethodTable
:> !dumpmt -md 00212eac
00212eac is not a MethodTable
:> !dumpmt -md 00212eac
00212eac is not a MethodTable
:> !dumpmt -md 00212eac
00212eac is not a MethodTable
:> !dumpmt -md 002137c0
EEClass: 0021125c
Module: 00212eac
Name: ConsoleApplication3.Program
mdToken:
File: C:\Users\ChenZhuo\Documents\visual studio \Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable:
Number of IFaces in IFaceMap:
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
69accd88 697e60bc PreJIT System.Object.ToString()
69ac6a90 697e60c4 PreJIT System.Object.Equals(System.Object)
69ac6660 697e60e4 PreJIT System.Object.GetHashCode()
69b467c0 697e60f8 PreJIT System.Object.Finalize()
0021c015 002137b8 NONE ConsoleApplication3.Program..ctor()
002137ac JIT ConsoleApplication3.Program.Main(System.String[])

  加了-md之后多出来了6个method description的信息,这就是那个Slots in VTable:6里面的6

  对于每个方法,上表有一列JIT指明了CLR是否已经对该方法进行了编译动作。上面有一个方法是JIT过了,是那个Main函数,另外的4个CLR已经预先做了JIT(为什么?想想GAC和NGEN.EXE)。那么对于具体的方法是否做过了JIT,我们可以用命令:!dumpmd来看,比如看上面的Main方法,那么!dumpmd 002137c0

0:007> !dumpmt 002137c0
EEClass: 0021125c
Module: 00212eac
Name: ConsoleApplication3.Program
mdToken: 02000002
File: C:\Users\ChenZhuo\Documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 6
Number of IFaces in IFaceMap: 0
0:007> !dumpmt -md 00212eac
00212eac is not a MethodTable
0:007> !dumpmt -md 00212eac
00212eac is not a MethodTable
0:007> !dumpmt -md 00212eac
00212eac is not a MethodTable
0:007> !dumpmt -md 00212eac
00212eac is not a MethodTable
0:007> !dumpmt -md 002137c0
EEClass: 0021125c
Module: 00212eac
Name: ConsoleApplication3.Program
mdToken: 02000002
File: C:\Users\ChenZhuo\Documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 6
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
69accd88 697e60bc PreJIT System.Object.ToString()
69ac6a90 697e60c4 PreJIT System.Object.Equals(System.Object)
69ac6660 697e60e4 PreJIT System.Object.GetHashCode()
69b467c0 697e60f8 PreJIT System.Object.Finalize()
0021c015 002137b8 NONE ConsoleApplication3.Program..ctor()
00480050 002137ac JIT ConsoleApplication3.Program.Main(System.String[])
0:007> !dumpmd 00480050
00480050 is not a MethodDesc
0:007> !dumpmd 00480050
00480050 is not a MethodDesc
0:007> !dumpmd 002137ac
Method Name: ConsoleApplication3.Program.Main(System.String[])
Class: 0021125c
MethodTable: 002137c0
mdToken: 06000001
Module: 00212eac
IsJitted: yes
CodeAddr: 00480050
Transparency: Critical

  上面最重要的结果就是有一个IsJitted的标志,这里是yes,表明它已经被compile过了,对于compile之后的native code,我们就可以用命令!u <m_codeoril>来观察。下命令:!u 00480050

0:007> !u 00480050
Normal JIT generated code
ConsoleApplication3.Program.Main(System.String[])
Begin 00480050, size 32
*** WARNING: Unable to verify checksum for C:\Users\ChenZhuo\Documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe C:\Users\ChenZhuo\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs @ 14:
>>> 00480050 55 push ebp
00480051 8bec mov ebp,esp
00480053 83ec10 sub esp,10h
00480056 894dfc mov dword ptr [ebp-4],ecx
00480059 833d7831210000 cmp dword ptr ds:[213178h],0
00480060 7405 je 00480067
00480062 e8dcc98470 call clr!GetHistoryFileDirectory+0x8b758 (70ccca43) (JitHelp: CORINFO_HELP_DBG_IS_JUST_MY_CODE)
00480067 90 nop C:\Users\ChenZhuo\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs @ 15:
00480068 8b0d7021eb02 mov ecx,dword ptr ds:[2EB2170h] ("Hello, Windbg!")
*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\045c9588954c3662d542b53f4462268b\mscorlib.ni.dll
0048006e e885796569 call mscorlib_ni+0x2f79f8 (69ad79f8) (System.Console.WriteLine(System.String), mdToken: 06000995)
00480073 90 nop C:\Users\ChenZhuo\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs @ 17:
00480074 8d4df0 lea ecx,[ebp-10h]
00480077 e82460d369 call mscorlib_ni+0x9d60a0 (6a1b60a0) (System.Console.ReadKey(), mdToken: 06000974)
0048007c 90 nop C:\Users\ChenZhuo\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs @ 18:
0048007d 90 nop
0048007e 8be5 mov esp,ebp
00480080 5d pop ebp
00480081 c3 ret

  见到源代码了,字符串都看到了。

  如果我们想看看StreamReader里面有哪些方法,应该用什么命令呢?

  命令:!name2ee mscorlib_ni!System.IO.StreamReader.ReadBuffer

0:007> !name2ee mscorlib_ni!System.IO.StreamReader.ReadBuffer
Module: 697e1000
Assembly: mscorlib.dll
Token: 06004733
MethodDesc: 6985f3dc
Name: System.IO.StreamReader.ReadBuffer()
JITTED Code Address: 69b18020
-----------------------
Token: 0600473f
MethodDesc: 6985f460
Name: System.IO.StreamReader.ReadBuffer(Char[], Int32, Int32, Boolean ByRef)
JITTED Code Address: 69b763d0

  拿到了Method Description的地址后执行:!dumpmd 6985f3dc

0:007> !dumpmd 6985f3dc
Method Name: System.IO.StreamReader.ReadBuffer()
Class: 6983e558
MethodTable: 69ba8fd0
mdToken: 06004733
Module: 697e1000
IsJitted: yes
CodeAddr: 69b18020
Transparency: Transparent

  再执行!dumpmt -md 69ba8fd0,就可以得到这个class的所有method信息

:> !dumpmt -md 69ba8fd0
EEClass: 6983e558
Module: 697e1000
Name: System.IO.StreamReader
mdToken:
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
BaseSize: 0x40
ComponentSize: 0x0
Slots in VTable:
Number of IFaces in IFaceMap:
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
69accd88 697e60bc PreJIT System.Object.ToString()
69ac6a90 697e60c4 PreJIT System.Object.Equals(System.Object)
69ac6660 697e60e4 PreJIT System.Object.GetHashCode()
69b467c0 697e60f8 PreJIT System.Object.Finalize()
69b7f310 PreJIT System.MarshalByRefObject.GetLifetimeService()
69aafd70 6987255c PreJIT System.MarshalByRefObject.InitializeLifetimeService()
69b6fdbc PreJIT System.MarshalByRefObject.CreateObjRef(System.Type)
69b1bbe0 6985f360 PreJIT System.IO.StreamReader.Close()
69b4ea80 6985ce74 PreJIT System.IO.TextReader.Dispose()
69b17a80 6985f368 PreJIT System.IO.StreamReader.Dispose(Boolean)  ... ...省略一部分

Windbg CLR基础小测 《第六篇》的更多相关文章

  1. 一种基于Qt的可伸缩的全异步C/S架构服务器实现(流浪小狗,六篇,附下载地址)

    本文向大家介绍一种基于Qt的伸缩TCP服务实现.该实现针对C/S客户端-服务集群应用需求而搭建.连接监听.数据传输.数据处理均在独立的线程池中进行,根据特定任务不同,可安排负责监听.传输.处理的线程数 ...

  2. MongoDB基础教程系列--第六篇 MongoDB 索引

    使用索引可以大大提高文档的查询效率.如果没有索引,会遍历集合中所有文档,才能找到匹配查询语句的文档.这样遍历集合中整个文档的方式是非常耗时的,特别是处理大数据时,耗时几十秒甚至几分钟都是有可能的. 创 ...

  3. #Java学习之路——基础阶段(第六篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  4. List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇

    最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java ...

  5. Linux基础介绍【第六篇】

    定时任务crond介绍 crond是什么? crond是linux系统中用来定期执行命令或指定程序任务的一种服务或软件.一般情况下,安装完CentOS5/6 linux操作系统之后,默认便会启动cro ...

  6. Python之路【第十六篇】:Django【基础篇】

    Python之路[第十六篇]:Django[基础篇]   Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...

  7. NHibernate 组件基础 (第六篇)

    NHibernate 组件基础 (第六篇) 一.组件简介 组件(Component)可以理解为被一个对象所包含的对象而持久化,而并非一个实体.简单说来,假如数据库有FirstName,LastName ...

  8. net core Webapi基础工程搭建(六)——数据库操作_Part 2

    目录 前言 开始 使用 小结 前言 昨天是写着写着发现,时间不早了,已经养成了晚上下班抽时间看看能写点儿啥的习惯(貌似),今天实在是不想让昨天没做完的事情影响,所以又坐下,沉下心(周末了),开始把数据 ...

  9. python爬取微信小程序(实战篇)

    python爬取微信小程序(实战篇) 本文链接:https://blog.csdn.net/HeyShHeyou/article/details/90452656 展开 一.背景介绍 近期有需求需要抓 ...

随机推荐

  1. C++ 常见崩溃问题分析

    一.前言 从事自动化测试平台开发的编程实践中,遭遇了几个程序崩溃问题,解决它们颇费了不少心思,解决过程中的曲折和彻夜的辗转反侧却历历在目,一直寻思写点东西,为这段难忘的经历留点纪念,总结惨痛的教训带来 ...

  2. 内网Linux对公网开启SSH

    1.首先你得装个Linux,过程就不说了.Linux可以装在Vmware上,但是网络适配器选项选的是桥接模式 2.在linux上安装SSH服务,如果有就自动忽略 3.在路由器上开启端口映射. 这里我用 ...

  3. GDI+ 中发生一般性错误。

    GDI+ 中发生一般性错误. “/wechat”应用程序中的服务器错误. GDI+ 中发生一般性错误. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及 ...

  4. android js调试

    http://blog.allenm.me/ 其他平台去这篇文章看 //js调试调试功能支持4.4版本以上的 if(Build.VERSION.SDK_INT >= Build.VERSION_ ...

  5. Maven内置隐式变量(转)

    Maven提供了三个隐式的变量可以用来访问环境变量,POM信息,和Maven Settings env env变量,暴露了你操作系统或者shell的环境变量.便 如在Maven POM中一个对${en ...

  6. 拥抱 Android Studio 之五:Gradle 插件开发

    实践出真知 笔者有位朋友,每次新学一门语言,都会用来写一个贪吃蛇游戏,以此来检验自己学习的成果.笔者也有类似体会.所谓纸上得来终觉浅,绝知此事要躬行.这一章,笔者将以开发和发布一个 Gradle 插件 ...

  7. rails 配置使用mysql

    1 在gemfile中要添加 gem 'mysql2' 2 在mysql数据库中创建三个数据库 dept_dev dept_test dept_pro 3 配置文件 default: &def ...

  8. 创建指定日期java Date对象

    import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import ...

  9. 什么是bower

    Bower是一个客户端技术的软件包管理器,它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源.其他一些建立在Bower基础之上的开发工具,如YeoMan和Grunt,这个会 ...

  10. .NET 文件相关的所有操作

    public static class FileSystemHelper { #region 检测指定目录是否存在 /// <summary> /// 检测指定目录是否存在 /// < ...