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++本地代码调试

帖子发起人: zhaohui2   发起时间: 2014-12-03 19:36 下午   回复: 5

Print Search
帖子排序:    
   2014-12-03, 19:36 下午
SkyDown 离线,最后访问时间: 2017/5/20 7:47:23 zhaohui2

发帖数前50位
注册: 2013-06-19
发 贴: 19
请教一个关于堆的问题
Reply Quote
学习堆的时候遇到一个很奇怪的问题
debug版本下调用HeapSize()会引发异常(Release 版本就不会).

这个是引发异常的代码

PCHAR str = (PCHAR)malloc(10);
HeapSize(GetProcessHeap(),0,str);

用windbg调试,给出如下的信息:
0:000> g
HEAP[EnumProcess.exe]: Invalid address specified to RtlSizeHeap( 00A30000, 00A3CD80 )
(a7c.16a4): Break instruction exception - code 80000003 (first chance)
eax=7ee6f000 ebx=00a3cd78 ecx=00a3cd78 edx=0000003f esi=00a30000 edi=00a3cd80
eip=773e05be esp=0098f964 ebp=0098f97c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ntdll!RtlpBreakPointHeap+0x19:
773e05be cc              int     3

请问张老师,为什么会出现这样的情况


IP 地址: 已记录   报告
   2014-12-04, 01:30 上午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: 请教一个关于堆的问题
Reply Quote
因为malloc只分了10个字节,可能是从CRT的LBH堆上分配的,所以把这个地址给Win32堆就是无效堆地址了,Debug版通过INT3报告了,release版本可能静默失败了。

把分配大小改大,比如4000,试一下

IP 地址: 已记录   报告
   2014-12-04, 22:10 下午
SkyDown 离线,最后访问时间: 2017/5/20 7:47:23 zhaohui2

发帖数前50位
注册: 2013-06-19
发 贴: 19
Re: 请教一个关于堆的问题
Reply Quote
用4000试了,还是同样的异常
IP 地址: 已记录   报告
   2015-09-20, 16:39 下午
CutlerMao 离线,最后访问时间: 2015/10/14 6:24:46 CutlerMao

发帖数前500位
注册: 2015-09-19
发 贴: 4
Re: 请教一个关于堆的问题
Reply Quote
Release模式下:
malloc最终会调用HeapAlloc(实际上是:RtlAllocateHeap),这种内存分配条件下,我们得到的UserPtr前面8个字节会放置一个叫做_HEAP_ENTRY的结构,这里面会描述UserPtr所指向的空间的大小。
在Release模式下,malloc和直接调用HeapAlloc,均是以上行为。

Debug模式下(与Release稍有不同):
malloc从CRT堆中分配内存,CRT堆在Debug模式下有自己的一套,UserPtr前面20个字节是一个叫做_CrtMemBlockHeader的结构,而不是_HEAP_ENTRY的结构。问题来了~ HeapSize(实际上是:RtlSizeHeap)的调用会假定你所给出的UserPtr前面的8个字节是_HEAP_ENTRY,但很不幸,你给的UserPtr前面是一个_CrtMemBlockHeader结构。HeapSize并不完全相信你给的参数的合法性,所以其实现内部会如下这样:
if (DEBUG_HEAP( Flags )) {

        return RtlDebugSizeHeap( HeapHandle, Flags, BaseAddress );
    }
也就是说,如果发现所使用的堆有调试标记,则检查你给的参数的合法性,结果检查没有通过,直接int 3断下来,给你一次改成错误的机会。

IP 地址: 已记录   报告
   2015-10-29, 12:58 下午
chena_cpp 离线,最后访问时间: 2012/12/21 8:18:23 chena_cpp

发帖数前100位
注册: 2012-12-21
发 贴: 11
Re: 请教一个关于堆的问题
Reply Quote
好像分配小块内存并不会每次都创建一个_HEAP_ENTRY,我new了几万次,然后用windbg看,_HEAP_ENTRY只有几百个。
IP 地址: 已记录   报告
   2015-11-01, 14:50 下午
john 离线,最后访问时间: 2006/10/19 16:20:30 irp

发帖数前200位
注册: 2006-10-19
发 贴: 5
Re: 请教一个关于堆的问题
Reply Quote
GetProcessHeap() => process default heap
malloc() => crt heap (static or dll), crt都是private heap, 不是process default heap.
你传给HeapSize()的是无效堆句柄,当然会出错。release 关掉了报错,debug下raiseexception是帮助调试的手段。

IP 地址: 已记录   报告
高端调试 » 软件调试 » C/C++本地代码调试 » Re: 请教一个关于堆的问题

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