代码改变世界

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

  王克伟  阅读(590)  评论(0编辑  收藏  举报

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

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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;

查看代码:

1
2
3
4
5
6
7
8
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));

问题解决。

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示