Advanced Debugging
About AdvDbg Consult Train Services Products Tools Community Contact  
欢迎光临 高端调试 登录 | 注册 | FAQ
 
  ACPI调试
Linux内核调试
Windows内核调试
 
  调试战役
调试原理
新工具观察
 
  Linux
Windows Vista
Windows
 
  Linux驱动
WDF
WDM
 
  PCI Express
PCI/PCI-X
USB
无线通信协议
 
  64位CPU
ARM
IA-32
  CPU Info Center
 
  ACPI标准
系统认证
Desktop
服务器
 
  Embedded Linux
嵌入式开发工具
VxWorks
WinCE
嵌入式Windows
 
  格蠹调试套件(GDK)
  格蠹学院
  小朱书店
  老雷的微博
  《软件调试》
  《格蠹汇编》
  《软件调试(第二版)》
沪ICP备11027180号-1

C/C++本地代码调试

帖子发起人: Forward   发起时间: 2011-06-07 16:12 下午   回复: 9

Print Search
帖子排序:    
   2011-06-07, 16:12 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

大家好:

     我又仔细看了下《软件调试》中的23章。并做了一些实验。出了个很奇怪的问题:

     如果不定义任何的调试标记!gflag -htc -hfc –hpc,New NtGlobalFlag contents: 0x00000000 那么在释放堆的时候,堆既没有被释放,也没有添加到空闲链表当中。但是当进行堆验证的时候,堆却忽然将这2个空闲块释放了。。。

     源代码:就是分配了1个私有堆,之后再从这个堆上分配了2次堆块,并且均释放。

        void heaperr()
       {
                HANDLE hHeap=NULL;
                int   bRet = false;
                void* p = NULL;

               hHeap=HeapCreate(0, 4096, 0);
               p = HeapAlloc(hHeap, 0, 128);
               bRet=HeapFree(hHeap, 0, p);

                p = HeapAlloc(hHeap, 0, 256);
                bRet=HeapFree(hHeap, 0, p);


                bRet=HeapValidate(hHeap, 0, NULL); 
                bRet=HeapDestroy(hHeap);

               return ;
         }


IP 地址: 已记录   报告
   2011-06-07, 16:14 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

这是第二次分配堆块512B,这里也可以看到上次分配的堆块128B并没有被释放

0:000> !heap 3a0000 -a

Index   Address  Name      Debugging options enabled

  5:   003a0000

    Segment at 003a0000 to 003b0000 (00003000 bytes committed)

    Flags:                00001002

    ForceFlags:           00000000

    Granularity:          8 bytes

    Segment Reserve:      00100000

    Segment Commit:       00002000

    DeCommit Block Thres: 00000200

    DeCommit Total Thres: 00002000

    Total Free Size:      000001fd

    Max. Allocation Size: 7ffdefff

    Lock Variable at:     003a0608

    Next TagIndex:        0000

    Maximum TagIndex:     0000

    Tag Entries:          00000000

    PsuedoTag Entries:    00000000

    Virtual Alloc List:   003a0050

    UCR FreeList:        003a0598

    FreeList Usage:      00000000 00000000 00000000 00000000

    FreeList[ 00 ] at 003a0178: 003a2020 . 003a2020 

        003a2018: 00108 . 00fe8 [10] - free

    Segment00 at 003a0640:

        Flags:           00000000

        Base:            003a0000

        First Entry:     003a0680

        Last Entry:      003b0000

        Total Pages:     00000010

        Total UnCommit:  0000000d

        Largest UnCommit:0000d000

        UnCommitted Ranges: (1)

            003a3000: 0000d000

 

    Heap entries for Segment00 in Heap 003a0000

        003a0000: 00000 . 00640 [01] - busy (640)

        003a0640: 00640 . 00040 [01] - busy (40)

        003a0680: 00040 . 01808 [01] - busy (1800)

        003a1e88: 01808 . 00088 [01] - busy (80)

        003a1f10: 00088 . 00108 [01] - busy (100)

        003a2018: 00108 . 00fe8 [10]

        003a3000:      0000d000      - uncommitted bytes.

 


IP 地址: 已记录   报告
   2011-06-07, 16:15 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

这是第二次释放堆块,这里看出,和第一次一样堆没有释放,而且在堆空闲链表中也没有记录。

0:000> !heap 003a0000 -a

Index   Address  Name      Debugging options enabled

  5:   003a0000

    Segment at 003a0000 to 003b0000 (00003000 bytes committed)

    Flags:                00001002

    ForceFlags:           00000000

    Granularity:          8 bytes

    Segment Reserve:      00100000

    Segment Commit:       00002000

    DeCommit Block Thres: 00000200

    DeCommit Total Thres: 00002000

    Total Free Size:      000001fd

    Max. Allocation Size: 7ffdefff

    Lock Variable at:     003a0608

    Next TagIndex:        0000

    Maximum TagIndex:     0000

    Tag Entries:          00000000

    PsuedoTag Entries:    00000000

    Virtual Alloc List:   003a0050

    UCR FreeList:        003a0598

    FreeList Usage:      00000000 00000000 00000000 00000000

    FreeList[ 00 ] at 003a0178: 003a2020 . 003a2020 

        003a2018: 00108 . 00fe8 [10] - free

    Segment00 at 003a0640:

        Flags:           00000000

        Base:            003a0000

        First Entry:     003a0680

        Last Entry:      003b0000

        Total Pages:     00000010

        Total UnCommit:  0000000d

        Largest UnCommit:0000d000

        UnCommitted Ranges: (1)

            003a3000: 0000d000

 

    Heap entries for Segment00 in Heap 003a0000

        003a0000: 00000 . 00640 [01] - busy (640)

        003a0640: 00640 . 00040 [01] - busy (40)

        003a0680: 00040 . 01808 [01] - busy (1800)

        003a1e88: 01808 . 00088 [01] - busy (80)

        003a1f10: 00088 . 00108 [01] - busy (100)

        003a2018: 00108 . 00fe8 [10]

        003a3000:      0000d000      - uncommitted bytes.

 


IP 地址: 已记录   报告
   2011-06-07, 16:15 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

这是第二次释放堆块,这里看出,和第一次一样堆没有释放,而且在堆空闲链表中也没有记录。

0:000> !heap 003a0000 -a

Index   Address  Name      Debugging options enabled

  5:   003a0000

    Segment at 003a0000 to 003b0000 (00003000 bytes committed)

    Flags:                00001002

    ForceFlags:           00000000

    Granularity:          8 bytes

    Segment Reserve:      00100000

    Segment Commit:       00002000

    DeCommit Block Thres: 00000200

    DeCommit Total Thres: 00002000

    Total Free Size:      000001fd

    Max. Allocation Size: 7ffdefff

    Lock Variable at:     003a0608

    Next TagIndex:        0000

    Maximum TagIndex:     0000

    Tag Entries:          00000000

    PsuedoTag Entries:    00000000

    Virtual Alloc List:   003a0050

    UCR FreeList:        003a0598

    FreeList Usage:      00000000 00000000 00000000 00000000

    FreeList[ 00 ] at 003a0178: 003a2020 . 003a2020 

        003a2018: 00108 . 00fe8 [10] - free

    Segment00 at 003a0640:

        Flags:           00000000

        Base:            003a0000

        First Entry:     003a0680

        Last Entry:      003b0000

        Total Pages:     00000010

        Total UnCommit:  0000000d

        Largest UnCommit:0000d000

        UnCommitted Ranges: (1)

            003a3000: 0000d000

 

    Heap entries for Segment00 in Heap 003a0000

        003a0000: 00000 . 00640 [01] - busy (640)

        003a0640: 00640 . 00040 [01] - busy (40)

        003a0680: 00040 . 01808 [01] - busy (1800)

        003a1e88: 01808 . 00088 [01] - busy (80)

        003a1f10: 00088 . 00108 [01] - busy (100)

        003a2018: 00108 . 00fe8 [10]

        003a3000:      0000d000      - uncommitted bytes.

 


IP 地址: 已记录   报告
   2011-06-07, 16:15 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

这是第二次释放堆块,这里看出,和第一次一样堆没有释放,而且在堆空闲链表中也没有记录。

0:000> !heap 003a0000 -a

Index   Address  Name      Debugging options enabled

  5:   003a0000

    Segment at 003a0000 to 003b0000 (00003000 bytes committed)

    Flags:                00001002

    ForceFlags:           00000000

    Granularity:          8 bytes

    Segment Reserve:      00100000

    Segment Commit:       00002000

    DeCommit Block Thres: 00000200

    DeCommit Total Thres: 00002000

    Total Free Size:      000001fd

    Max. Allocation Size: 7ffdefff

    Lock Variable at:     003a0608

    Next TagIndex:        0000

    Maximum TagIndex:     0000

    Tag Entries:          00000000

    PsuedoTag Entries:    00000000

    Virtual Alloc List:   003a0050

    UCR FreeList:        003a0598

    FreeList Usage:      00000000 00000000 00000000 00000000

    FreeList[ 00 ] at 003a0178: 003a2020 . 003a2020 

        003a2018: 00108 . 00fe8 [10] - free

    Segment00 at 003a0640:

        Flags:           00000000

        Base:            003a0000

        First Entry:     003a0680

        Last Entry:      003b0000

        Total Pages:     00000010

        Total UnCommit:  0000000d

        Largest UnCommit:0000d000

        UnCommitted Ranges: (1)

            003a3000: 0000d000

 

    Heap entries for Segment00 in Heap 003a0000

        003a0000: 00000 . 00640 [01] - busy (640)

        003a0640: 00640 . 00040 [01] - busy (40)

        003a0680: 00040 . 01808 [01] - busy (1800)

        003a1e88: 01808 . 00088 [01] - busy (80)

        003a1f10: 00088 . 00108 [01] - busy (100)

        003a2018: 00108 . 00fe8 [10]

        003a3000:      0000d000      - uncommitted bytes.

 


IP 地址: 已记录   报告
   2011-06-07, 16:17 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

在进行堆验证后,可以看到前2次堆块全部被释放了。这是为什么呢???

0:000> !heap 003a0000 -a

Index   Address  Name      Debugging options enabled

  5:   003a0000

    Segment at 003a0000 to 003b0000 (00003000 bytes committed)

    Flags:                00001002

    ForceFlags:           00000000

    Granularity:          8 bytes

    Segment Reserve:      00100000

    Segment Commit:       00002000

    DeCommit Block Thres: 00000200

    DeCommit Total Thres: 00002000

    Total Free Size:      0000022f

    Max. Allocation Size: 7ffdefff

    Lock Variable at:     003a0608

    Next TagIndex:        0000

    Maximum TagIndex:     0000

    Tag Entries:          00000000

    PsuedoTag Entries:    00000000

    Virtual Alloc List:   003a0050

    UCR FreeList:        003a0598

    FreeList Usage:      00000000 00000000 00000000 00000000

    FreeList[ 00 ] at 003a0178: 003a1e90 . 003a1e90 

        003a1e88: 01808 . 01178 [10] - free

    Segment00 at 003a0640:

        Flags:           00000000

        Base:            003a0000

        First Entry:     003a0680

        Last Entry:      003b0000

        Total Pages:     00000010

        Total UnCommit:  0000000d

        Largest UnCommit:0000d000

        UnCommitted Ranges: (1)

            003a3000: 0000d000

 

    Heap entries for Segment00 in Heap 003a0000

        003a0000: 00000 . 00640 [01] - busy (640)

        003a0640: 00640 . 00040 [01] - busy (40)

        003a0680: 00040 . 01808 [01] - busy (1800)

        003a1e88: 01808 . 01178 [10]

        003a3000:      0000d000      - uncommitted bytes.

 


IP 地址: 已记录   报告
   2011-06-09, 20:13 下午
Thomson 离线,最后访问时间: 2013/3/31 11:42:42 Thomson

发帖数前10位
注册: 2008-07-03
发 贴: 211
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote
可能是被front-end (look aside list)给cache下来了,free的时候没没有真正的return 给heap back end.
IP 地址: 已记录   报告
   2011-06-10, 10:31 上午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

但是,为什么在free list中也没有记录呢?还有为什么一检测堆,就会被释放掉了呢??


IP 地址: 已记录   报告
   2011-06-11, 23:25 下午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote
确实如Tom所说,对于8-1024字节的小堆块,为了提高性能,在不启用调试机制的默认情况下,会先放到一个Look-aside列表中,这样比放到Free-List还要高效,不需要使用堆的全局锁
这个列表的头指针也记录在_HEAP结构中,但是公开的调试符号中没有包含这个字段
IP 地址: 已记录   报告
   2011-06-12, 19:17 下午
wbdwbd04 离线,最后访问时间: 2011/6/7 7:59:42 Forward

发帖数前25位
注册: 2009-12-23
发 贴: 50
Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000
Reply Quote

哦,谢谢Thomson,张老师。

在此对Thomson表示抱歉,我一开始没有认真琢磨,你的回复。


IP 地址: 已记录   报告
高端调试 » 软件调试 » C/C++本地代码调试 » Re: 堆释放,在无标记时。New NtGlobalFlag contents: 0x00000000

 
Legal Notice Privacy Statement Corporate Governance Corporate Governance
(C)2004-2020 ADVDBG.ORG All Rights Reserved.