代码改变世界

利用压力测试来保证软件的质量(七) 堆错误问题

2010-09-10 21:12  王克伟  阅读(585)  评论(0编辑  收藏  举报

堆错误(Heap Corruption)是非常常见的错误,因为读或者写非法的堆地址造成错误,解决这些问题的关键在于操作系统内存检查机制的完善,遇到问题时借助内存检查工具能够较轻松搞定,单单靠人工去解决不现实,特别在遇到内存使用越界或者野指针等问题时。

 

尝试解决\DumpFile\Heap Corruption\20100702_MACHINEENROLLERLAUNCH.EXE

Windows CE>!diagnose 1 
======================================================= 
| 
|  Heap corruption 'Bad item tail signature' detected in MACHINEENROLLERLAUNCH.EXE 
| 
======================================================= 

Heap allocations are aligned to a heap block size of 16 bytes. 
When heap sentinels are enabled the difference between the requested 
allocation size and the 16 byte block boundary is filled with a tail 
signature. 

The tail signature of the following item appears to be corrupt.  The 
most likely cause is a heap item over-run, i.e. an app has written to 
memory beyond the requested heap item size. 

addr           value 
========================== 
header                     
========================== 
0x0004bfa0  :  0xa9e4b608   Signature (expect 0xa9e4b620) 
0x0004bfa4  :  0x000000c8   Data size (bytes) 
0x0004bfa8  :  0x0002194e   MACHINEENROLLERLAUNCH.EXE ! CDeviceEnrollerUI::OnDrawItem + 0x2f 
0x0004bfac  :  0x000222c1   MACHINEENROLLERLAUNCH.EXE ! CDeviceEnrollerUI::DlgProc + 0x8b 
0x0004bfb0  :  0x0002246e   MACHINEENROLLERLAUNCH.EXE ! CDeviceEnrollerUI::s_DlgProcWrap + 0x3f 
0x0004bfb4  :  0xfffffdfe   0xfffffdfe 
0x0004bfb8  :  0x00000000   0x00000000 
0x0004bfbc  :  0x00000000   0x00000000 
========================== 
data 
========================== 
0x0004bfc0  :  0x673a8054 
0x0004bfc4  :  0x79c19690 
0x0004bfc8  :  0x660e58f0 
0x0004bfcc  :  0x00000000 
0x0004bfd0  :  0x00000000 
0x0004bfd4  :  0x00000000 
0x0004bfd8  :  0x00000000 
0x0004bfdc  :  0x00000000 
0x0004bfe0  :  0x00000000 
0x0004bfe4  :  0x00000000 
0x0004bfe8  :  0x00000000 
0x0004bfec  :  0x00000000 
0x0004bff0  :  0x00000000 
0x0004bff4  :  0x00000000 
0x0004bff8  :  0x00000000 
0x0004bffc  :  0x00000000 
0x0004c000  :  0x00000000 
0x0004c004  :  0x00000000 
0x0004c008  :  0x00000000 
0x0004c00c  :  0x00000000 
0x0004c010  :  0x00000000 
0x0004c014  :  0x00000000 
0x0004c018  :  0x00000000 
0x0004c01c  :  0x00000000 
0x0004c020  :  0x00000000 
0x0004c024  :  0x00000000 
0x0004c028  :  0x00000000 
0x0004c02c  :  0x00000000 
0x0004c030  :  0x00000000 
0x0004c034  :  0x00000000 
0x0004c038  :  0x00000000 
0x0004c03c  :  0x00000000 
0x0004c040  :  0x00000000 
0x0004c044  :  0x00000000 
0x0004c048  :  0x00000000 
0x0004c04c  :  0x00000000 
0x0004c050  :  0x00000000 
0x0004c054  :  0x00000000 
0x0004c058  :  0x00000000 
0x0004c05c  :  0x00000000 
0x0004c060  :  0x00000000 
0x0004c064  :  0x00000000 
0x0004c068  :  0x00000000 
0x0004c06c  :  0x00000000 
0x0004c070  :  0x00000000 
0x0004c074  :  0x00000000 
0x0004c078  :  0x00000000 
0x0004c07c  :  0x00000000 
0x0004c080  :  0x00000000 
0x0004c084  :  0x00000000 
0x0004c088  :  0x00000000  <====== End of data 0x0004c088 
0x0004c08c  :  0x00000000 
0x0004c090  :  0x00000000 
0x0004c094  :  0x00000000 
0x0004c098  :  0x00000000 
0x0004c09c  :  0x00000000 

Tags for bug matcher: 
+DEFECT:CRASH:HEAP_CORRUPTION:MACHINEENROLLERLAUNCH.EXE:|Type=Bad item tail signature; 

查看代码:

BOOL CDeviceEnrollerUI::OnDrawItem(__in LPDRAWITEMSTRUCT pdis) 
{ 
    ... 
    // get the button text for the hyperlink 
    apszDlgItemTxt = static_cast<LPTSTR>(LocalAlloc(LMEM_FIXED, c_nDlgItemTxtMaxLen)); //这里分配内存 
    CBREx(apszDlgItemTxt.valid(), E_OUTOFMEMORY); 
    ... 
} 

查看一下:
    const int       c_nDlgItemTxtMaxLen = 200;
刚好就是header上面标识的大小:
0x0004bfa4  :  0x000000c8   Data size (bytes)

这段内存稍后做如下使用:
    cchButtonTxt = GetDlgItemText(m_hwnd, pdis->CtlID, apszDlgItemTxt, (c_nDlgItemTxtMaxLen - 1));
可能造成溢出,应该内存分配部分修改为下面的:
    apszDlgItemTxt = static_cast<LPTSTR>(LocalAlloc(LMEM_FIXED, sizeof(TCHAR)*c_nDlgItemTxtMaxLen));

问题解决。