|
|
|
|
|
|
|
C/C++本地代码调试
帖子发起人: zhaohui2 发起时间: 2014-12-03 19:36 下午 回复: 5
|
帖子排序:
|
|
|
|
2014-12-03, 19:36 下午
|
zhaohui2
注册: 2013-06-19
发 贴: 19
|
|
|
学习堆的时候遇到一个很奇怪的问题 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, 22:10 下午
|
zhaohui2
注册: 2013-06-19
发 贴: 19
|
|
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2015-09-20, 16:39 下午
|
CutlerMao
注册: 2015-09-19
发 贴: 4
|
|
|
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
发 贴: 11
|
|
|
好像分配小块内存并不会每次都创建一个_HEAP_ENTRY,我new了几万次,然后用windbg看,_HEAP_ENTRY只有几百个。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2015-11-01, 14:50 下午
|
irp
注册: 2006-10-19
发 贴: 5
|
|
|
GetProcessHeap() => process default heap malloc() => crt heap (static or dll), crt都是private heap, 不是process default heap. 你传给HeapSize()的是无效堆句柄,当然会出错。release 关掉了报错,debug下raiseexception是帮助调试的手段。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
高端调试 » 软件调试 » C/C++本地代码调试 » 请教一个关于堆的问题
|
|
|
|
|
|