内存是存储数据、代码的地方,通过内存查看命令可以分析很多问题。相关命令可以分为:内存查看命令和内存统计命令。内存统计命令用来分析内存的使用状况。

一、查看内存

  有非常丰富的内存查看命令,它们被容易为d*格式,如下所示:

  • d[类型] [地址范围]

  d代表Display,类型包括:字符、字符串、双字等。具体来说,d*命令共有这几种:d、da、db、dc、dd、dD、df、dp、dq、du、dw、dW、dyb、dyd、ds、dS。

  1、内存类型

  基本类型

  • dw = 双字节WORD格式;
  • dd = 4字节DWORD格式 ;
  • dq = 8字节格式;
  • df = 4字节单精度浮点数格式;
  • dD =8字节双精度浮点数格式;
  • dp = 指针大小格式,32位系统下4字节,64位系统下为8字节;

  基本字符串

  • da = ASCII字符串格式;
  • du = UNICODE字符串格式;
  • db =字节 + ASCII字符串;
  • dW = 双字节WORD + ASCII字符串;
  • dc = 4字节DWORD + ASCII字符串;

  高级字符串:

  • ds = ANSI_STRING类型字符串格式;
  • dS = UNICODE_STRING类型字符串格式;

  二进制 + 基本类型

  • byb = 二进制 + 字节;
  • byd = 二进制 + DWORD值;

  /c 列数:指定列数。默认情况下,列数 等于16除以列长,如dd命令的默认列数即为4列(=16/4)。例:

  • dd  /c  8

  此命令每列显示8个DWORD数,即32字节内容。

  /p:此选项用来显示物理内存信息,只能用于内核模式中。不使用此命令时,都将显示虚拟内存信息。如:

  • d  /p  [地址范围]

  L 长度: 默认情况下,d命令只显示固定长度的内存,一般为128或64字节。L可指定长度,如下面的命令将显示地址0×80000000开始处的0×100个字节内容:

  • db  0×80000000  L100 

  2、数组形式内存

  难能可贵的是,d*命令还能够以数组形式显示一段内存信息,包括:dda, ddp、 ddu、dds、dpa、dpp、dpu、dps、dqa、dqp、dqu、dqs。

  何谓“以数组形式显示”呢?这一组命令能够将指定地址处的内容,作为一系列指针,进而显示指针所指处内容。听上去有点拗口吧,读者这样想会清楚些:前一组命令显示address值,本节这一组命令显示*address值。

  程序代码中如有类似“char *array[10]”的数组变量,可使用这些命令显示数组内容。下面会有例子。这一系列命令实则由第一组命令演化而来,可分为三组:

  • 4字节DWORD为单位的dd*系列数组指令;
  • 指针长度为单位的dp*系列数组指令;
  • 8字节为单位的dq*系列数组指令。

  3、查看链表内存

  最后,d*命令的另一个变体是以链表形式显示内存内容。命令如下:

  • dl  开始地址

  默认情况下,以正向从头到尾遍历链表;也可反向(由尾向头)遍历,指定b开关选项:

  • dl  b  尾地址

  应注意的是,命令dl是Display List的缩写,这里的链表不能是用户自定义的链表,而专指符合LIST_ENTRY或SINGLE_LIST_ENTRY格式的链表。

二、内存信息

  系统的内核空间很大的,想知道这么广大的内存空间里面都有些什么东西吗?想要知道一个内存地址,到底是被一个内核栈使用着,亦或被堆管理器使用着吗?我们这一节就领大家看看内存的地理概况。首先看Address命令:

  • !address  [地址]

  显示进程或系统的内存状态、信息,!address是最好的工具。不加任何参数,在用户模式下此命令将以内存块为单位,列出从地址0开始到0×80000000(略小于)的全部地址空间信息;内核模式下,将列出从地址0×80000000开始到0xFFFFFFFF(略小于)的全部地址空间信息;如指定地址值,则将显示此地址所在内存块的内存信息(此命令在Vista以后系统中,不能在内核模式下正常使用,此Bug应会在Windbg的以后版本中被修正)。下面分别截取了用户与内核空间中的内存信息片段:

:> !address                            

        BaseAddress      EndAddress+        RegionSize     Type       State                 Protect             Usage
------------------------------------------------------------------------------------------------------------------------
+ ` ` ` MEM_FREE PAGE_NOACCESS Free
+ ` ` ` MEM_MAPPED MEM_COMMIT PAGE_READWRITE Heap64 [ID: ; Handle: ; Type: Segment]
+ ` ` ` MEM_PRIVATE MEM_COMMIT PAGE_READWRITE
+ ` ` `0000f000 MEM_FREE PAGE_NOACCESS Free
+ ` ` ` MEM_PRIVATE MEM_COMMIT PAGE_READWRITE
// 省略很多...

  上图截取了两段用户区内存,第一段从0开始,长度0×10000,状态为释放(FREE),表明这一段地址空间不可用;第二段从0×10000开始,长度0×1000,属于私有内存,状态为已提交,保护模式为可读写,此内存块被用于环境块。

  下面给大家解释一下内存块中的几个值:

  内存类型:即Type值,共有四种:第一种是什么都不是,即尚未被使用的;第二种是MEM_IMAGE,即地址映射于一个可执行镜像文件片段,如DLL文件;第三种是MEM_ MAPPED,即地址映射于不可执行的镜像文件片段,如页文件;第四种是MEM_PRIVATE,即私有有内存,这里的私有是针对进程而言的,私有内存无法在多个进程间共享;

  保护模式:即Protect值,上例中见识了两种保护模式,NOACCESS和READWRITE。从字面即很容易理解其意思,前者是不能做任何访问的,因为空闲内存是无效内存;后者则可读可写,但不能执行,说明是保存数据的地方。所有可用的保护包括:PAGE_NOACCESS(不可访问),PAGE_READONLY(只读),PAGE_READWRITE(读写),PAGE_EXECUTE(可执行), PAGE_EXECUTE_READ(执行并可读),PAGE_EXECUTE_READWRITE(执行并可读写),PAGE_WRITECOPY(写时拷贝),PAGE_EXECUTE_WRITECOPY(执行,并写时拷贝), PAGE_GUARD(保护)。

  内存状态:即State值,共三种:MEM_FREE,即空闲内存;MEM_RESERVED,即保留内存,保留内存尚不能被实际使用,但其地址空间已被预留,尚需一个提交动作。最后是MEM_COMMIT,即内存已被提交,正在被使用。

  内存用途:即Usage值,有这样一些值和用途。RegionUsageIsVAD:表示此地址区域已被分配;RegionUsageFree:代表此地址区域已被释放,既没有保留也没有被提交,将来可以申请使用;

  • RegionUsageImage:代表此地址区域被映射到二进制文件的镜像;Region UsageStack:代表此地址区域用于线程栈;RegionUsageTeb:代表此地址区域用于保存目标进程的所有线程的TEB结构;
  • RegionUsageHeap:代表此地址区域用于堆内存;RegionUsage Pdb:代表此地址区域用于保存目标进程的PEB结构;RegionUsageProcessParameters:代表此内存块用于保存目标进程的启动参数;
  • RegionUsageEnviromentBlock:代表此地址区域用于保存目标进程的环境块。

  用户环境下可使用下面的命令显示内存统计信息,包括内存用途、内存类型、内存状态。

  • !address  -summary
:> !address  -summary

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free `7a5ba000 ( 1.912 Gb) 95.60%
Image `022b8000 ( 34.719 Mb) 38.49% 1.70%
`0113a000 ( 17.227 Mb) 19.10% 0.84%
Stack32 ` ( 17.000 Mb) 18.84% 0.83%
Heap32 `006e0000 ( 6.875 Mb) 7.62% 0.34%
MappedFile `0069e000 ( 6.617 Mb) 7.34% 0.32%
Stack64 ` ( 4.250 Mb) 4.71% 0.21%
Other `001c1000 ( 1.754 Mb) 1.94% 0.09%
Heap64 ` ( 1.563 Mb) 1.73% 0.08%
TEB64 ` ( 136.000 kb) 0.15% 0.01%
TEB32 ` ( 68.000 kb) 0.07% 0.00%
PEB64 ` ( 4.000 kb) 0.00% 0.00%
PEB32 ` ( 4.000 kb) 0.00% 0.00% --- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE `02f11000 ( 47.066 Mb) 52.17% 2.30%
MEM_IMAGE `022b9000 ( 34.723 Mb) 38.49% 1.70%
MEM_MAPPED `0086c000 ( 8.422 Mb) 9.34% 0.41% --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE `7a5ba000 ( 1.912 Gb) 95.60%
MEM_RESERVE `02f5d000 ( 47.363 Mb) 52.50% 2.31%
MEM_COMMIT `02ad9000 ( 42.848 Mb) 47.50% 2.09% --- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_EXECUTE_READ ` ( 20.078 Mb) 22.26% 0.98%
PAGE_READONLY `0117a000 ( 17.477 Mb) 19.37% 0.85%
PAGE_READWRITE `004b5000 ( 4.707 Mb) 5.22% 0.23%
PAGE_WRITECOPY `0004c000 ( 304.000 kb) 0.33% 0.01%
PAGE_READWRITE|PAGE_GUARD ` ( 288.000 kb) 0.31% 0.01%
PAGE_EXECUTE_READWRITE ` ( 8.000 kb) 0.01% 0.00% --- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free `030b0000 `6cf40000 ( 1.702 Gb)
Image `75d71000 ` ( 8.473 Mb)
`7f0e0000 `00f00000 ( 15.000 Mb)
Stack32 `00cd0000 `000fd000 (1012.000 kb)
Heap32 `02f13000 `0019d000 ( 1.613 Mb)
MappedFile `01a90000 `002cf000 ( 2.809 Mb)
Stack64 ` ` ( 228.000 kb)
Other `006b0000 ` ( 1.504 Mb)
Heap64 `02b90000 `000bf000 ( 764.000 kb)
TEB64 `7ef76000 ` ( 8.000 kb)
TEB32 `7ef78000 ` ( 4.000 kb)
PEB64 `7efdf000 ` ( 4.000 kb)
PEB32 `7efde000 ` ( 4.000 kb)

  上图分别以内存使用、内存类型、内存状态显示用户空间内存统计信息。

  和!address命令类似的,用户模式下还有下面两个命令可用:

  • !vprot  [地址]
  • !vadump  [-v]

  命令!vprot显示指定内存块的信息,侧重于内存保护信息;命令!vadump显示整个内存空间信息,dump者倾泻也,开启-v选项将显示详细(Verbose)信息。

  上面讲过,用户环境下使用“!address  –summary”可显示用户空间的内存统计信息;现在再看两个内核命令,在内核环境下显示内存的统计信息:

  • !memusage

  此命令从物理内存角度显示内存统计信息。无数个页表信息将被打印出来,可以说是“最内存”的信息。此命令会查看所有的页帧,所以运行时会非常地耗时。

  • !vm

  此命令从虚拟内存的角度显示内存统计信息,不仅能从全局角度显示虚拟内存的使用情况,还能以进程为单位显示内存使用情况。

三、其他命令

  内核模式下,查看文件缓存信息,命令格式如下:

  • !filecache

  此命令在用户内核模式下,显示文件缓存和页表状态。每一行信息表示一个虚拟地址控制块 (VACB)。虚拟地址控制块可能对应着一个命名文件,也可能对应着一个元数据块。如果对应着一个命名文件,则此文件名称将被显示,否则显示元数据名称。

  实验:查看文件缓存

很多软件都使用文件缓存的方式保存数据,比如Office Word。直接查看WORD文档,由于其
内部格式不透明,故而不便分析。但如果使用WORD打开一个txt文本文档,它就会以文本文档
的方式来处理之,并且依旧使用文件缓存的方式。 读者用WORD打开一个TXT文档(比如:测试.txt)。
运行内核调试器并执行!filecache命令,在打印信息中查找“测试.txt”。

  用户模式下查看堆信息,命令格式如下:

  • !heap

  下面的清单显示了某个进程中共有4个堆:

:> !heap -a
Index Address Name Debugging options enabled
:
Segment at to ( bytes committed) :
Segment at to ( bytes committed) :
Segment at to ( bytes committed) :
Segment at to 003a0000 ( bytes committed)
Segment at to (0007b000 bytes committed)

  堆资源是属于进程的,每个进程都会创建若干个堆,如C运行时堆、进程默认堆等。以第一个堆为例,地址范围是[0x150000,0x250000],已经有0×31000个字节被申请提交。

Windbg 内存命令 《第四篇》的更多相关文章

  1. Windbg 基础命令 《第一篇》

    Windbg.exe是Windows的一个调试工具,它支持两种调试模式,即“实时调试模式(Living)”和“事后调试模式(Postmortem)”. 实时模式:被调试的程序正在运行当中,调试器可以实 ...

  2. Linux命令第四篇

    作业四: 1)  新建目录/test/dir,属主为tom,数组为group1,/test目录的权限为777 # useradd tom [root@localhost /]# groupadd gr ...

  3. Windbg调试命令详解

    作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe.ntsd. ...

  4. WinDbg调试命令汇总

    一. 1. !address eax 查看对应内存页的属性 2. vertarget 显示当前进程的大致信息 3 !peb 显示process Environment Block 4. lmvm 可以 ...

  5. Windbg调试命令详解(1)

    转载注明>> [作者:张佩][镜像:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是 ...

  6. shell第四篇(上)

    第四篇了解Shell 命令执行流程图 {网中人大哥推荐参考Learning the Bash Shell, 2nd Edition,第 178页:中文版229页} Shell 从标准输入或脚本中读取的 ...

  7. 常用DOS命令之通俗易懂篇

    目录 常用DOS命令之通俗易懂篇 Arp 命令 Assoc 关联 At 计划服务 Attrib 属性 Cd=chdir 目录 Cipher Cls 清屏 Color 颜色 Comp 比较 Compac ...

  8. windbg 常用命令详解

    = kd> ln 8046e100 (8046e100) nt!KeServiceDescriptorTableShadow | (8046e140) nt!MmSectionExtendRes ...

  9. 【block第四篇】实现

    -------------------------------------------欢迎查看block连载博客[专栏]--------------------------------------[b ...

随机推荐

  1. 转--简单工厂模式 Simple Factory

    简单工厂模式的作用就是定义一个用于创建对象的接口 在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化.         先来看看它的组成: 1) 工厂类角色 ...

  2. java中treemap和treeset实现(红黑树)

    java中treemap和treeset实现(红黑树)   TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点. TreeSet 和 Tre ...

  3. SpringMVC静态资源处理[转]

    SpringMvc配置DispatchServlet对所有请求进行过滤: <servlet> <servlet-name>mvc-dispatcher</servlet- ...

  4. Software Engineer

    1, 软件工程师 软件工程师英文是Software Engineer,是从事软件职业的人员的一种职业能力的认证,通过它说明具备了工程师的资格.软件工程师是从事软件开发相关工作的人员的统称. 它是一个广 ...

  5. js实现的新闻列表垂直滚动实现详解

    js实现的新闻列表垂直滚动实现详解:新闻列表垂直滚动效果在大量的网站都有应用,有点自然是不言而喻的,首先由于网页的空间有限,使用滚动代码可以使用最小的空间提供更多的信息量,还有让网页有了动态的效果,更 ...

  6. android之Widget01

    ExampleAppWidgetProvider.java package com.example.mars_2600_widget01; import android.appwidget.AppWi ...

  7. nginx 均衡负载配置

    nginx详细配置介绍: 参考资料:http://blog.csdn.net/xmtblog/article/details/42295181 配置实例: // nginx服务器虚拟为代理服务器和we ...

  8. 手机端的各种默认样式比如 ios的按钮变灰色

    1.ios按钮变灰色,给按钮加样式: -webkit-appearance: none; 2.有圆角话 ; } 3.去除Chrome等浏览器文本框默认发光边框 input:focus, textare ...

  9. Html5中的跨页面消息传输

    1.如果要接受从其他的窗口那里发过来的消息,就必须对窗口对象的message事件进行监控. window.addEventListener("message",function() ...

  10. poj 1459 Power Network : 最大网络流 dinic算法实现

    点击打开链接 Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 20903   Accepted:  ...