!heap 和 _HEAP_ENTRY

简介: WinDBG提供了!heap命令帮助我们查找heap,同时我们也可以通过dt和MS SYMBOL来了解memory layout。 假设我们有下面一个小程序。 int _tmain(int argc, _TCHAR* argv[]){ char * pChar = new char[2]; pChar[0] = 'a';  delete [] pChar; return 0;} 在WinDbg里面启动这个程序,运行到new操作结束。

WinDBG提供了!heap命令帮助我们查找heap,同时我们也可以通过dt和MS SYMBOL来了解memory layout。

 

假设我们有下面一个小程序。

 

复制代码
int _tmain(int argc, _TCHAR* argv[])
{
char * pChar = new char[2];

pChar[0] = 'a';

  delete [] pChar;
return 0;
}
复制代码

 

在WinDbg里面启动这个程序,运行到new操作结束。这时候我们可以得到pChar指针。

我们可以通过!heap -x 来查找对应的Heap Block

 !heap -x 00343818
Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
00343810  00343818  00340000  00340640        20        38        1e  busy extra fill 
从上面我们知道,这个heap block地址是00343810,用户内存地址是00343818,整个heap block大小是0x20。Heap Block Meta Data占据了前面8个字节 (这也解释了为什么用户内存地址的起始地址)。未使用的空间有1e(因为我们申请了2个byte) Flags是busy。

有了Heap Block地址,我们就可以运行下面命令

0:000> dt _HEAP_ENTRY 0X00343810 
ntdll!_HEAP_ENTRY
   +0x000 Size             : 4
   +0x002 PreviousSize     : 7
   +0x000 SubSegmentCode   : 0x00070004 
   +0x004 SmallTagIndex    : 0x49 'I'
   +0x005 Flags            : 0x7 ''
   +0x006 UnusedBytes      : 0x1e ''
   +0x007 SegmentIndex     : 0 ''
我们可以看到Size 是4.为什么是4了?因为这儿的单位不是byte,而是heap granularity。通常是8.所以我们可以计算:4*8=32=0x20。

我们再看一下内存布局。

0:000> dd 00343810  
00343810  00070004 001e0749 abab0198 abababab
00343820  feeeabab feeefeee 00000000 00000000

上图是每个Heap Block的说明。对比我们的memory layout,我们就可以得到类似的信息。

 

我们也可以下面的命令来得到更详细的信息。

0:000> !heap -i 00343810  
Detailed information for block entry 00343810
Assumed heap       : 0x00340000 (Use !heap -i NewHeapHandle to change)
Owning segment     : 0x00340000 (offset 0)
Block flags        : 0x7 (busy extra fill )
Total block size   : 0x4 units (0x20 bytes)
Requested size     : 0x2 bytes (unused 0x1e bytes)
Previous block size: 0x7 units (0x38 bytes)
Previous block     : 0x003437d8
Next block         : 0x00343830

 

运行完pChar[0] = 'a';这条命令,我们再看看内存。

0:000> dc 00343818
00343818  abab0161 abababab feeeabab feeefeee  a...............

我们可以看到'a'写进去了。

目录
相关文章
|
5月前
|
存储 人工智能 程序员
技术心得记录:堆(heap)与栈(stack)的区别
技术心得记录:堆(heap)与栈(stack)的区别
40 0
|
存储 算法 Java
JVM系列(3):堆(Heap)
Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC堆”。
79 0
|
6月前
|
存储 Java 程序员
堆栈与堆(Stack vs Heap)有什么区别?
堆栈与堆(Stack vs Heap)有什么区别?
83 0
|
Docker 容器
解决Native memory allocation (mmap) failed to map 2060255232 bytes for committing reserved memory.
解决Native memory allocation (mmap) failed to map 2060255232 bytes for committing reserved memory.
1263 0
|
存储 Java
JVM系列(八):堆(Heap)的相关知识介绍
虚拟机栈也称为Java栈,Java每个main方法被执行的时候,JVM都会同步创建一个栈帧(Stack Frame),通过存储局部变量表、操作数栈、动态链接、方法出口等信息来支撑和完成方法的执行。栈帧就是虚拟机栈中的子单位。栈其实只有入栈和出栈两种操作。
JVM系列(八):堆(Heap)的相关知识介绍
|
存储 缓存 算法
堆(heap)和栈(stack)的区别
堆(heap)和栈(stack)的区别
240 0
堆(heap)和栈(stack)的区别
内存中的栈(stack)、堆(heap)和静态区(static area)的用法
通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、"hello"和常量都是放在静态区中。
1282 0
|
存储 缓存 监控
heap 和stack 有什么区别
heap 和stack 有什么区别
300 0