堆的调试
来源:互联网 发布:数码兽数据库 编辑:程序博客网 时间:2024/05/01 09:18
在有堆的基础认识之后,可以开始动手模拟与堆相关的调试技术。
1.堆简介
对的管理结构如下:
windows堆分为前端堆和后端堆,分配内存的过程如下:
释放内存的过程如下:
由于win7内核变化堆也产生了变化,使用如下代码验证分配和释放过程:
#include <windows.h>#include <cstdio>void __cdecl wmain (int argc, WCHAR* args[]){ BYTE* pAlloc1=NULL; BYTE* pAlloc2=NULL; HANDLE hProcessHeap=GetProcessHeap();printf("Heap addr:0x%08p\r\n",hProcessHeap); pAlloc1=(BYTE*) HeapAlloc(hProcessHeap, 0, 16); pAlloc2=(BYTE*) HeapAlloc(hProcessHeap, 0, 1500);printf("Heap addr1:0x%08p\r\n",pAlloc1);printf("Heap addr2:0x%08p\r\n",pAlloc2); // // Use allocated memory // HeapFree(hProcessHeap, 0, pAlloc1); HeapFree(hProcessHeap, 0, pAlloc2);}在wmain入口处下断点,检查堆的情况:
分别对比查看两个对的内容:
SegmentList->heap地址加上firstentry的偏移可见heap_segment被合并到heap中了,而且segmentlist也使用链表而非数组来实现了。由于heap_segment结构被编码了,暂时还不知道如何解析,故而不能遍历这个list。只能通过freelist和heap中freetotal的变化来查看下内存的分配过程:
2.堆破坏
内存问题都是由于对不正确的地址执行访问和写入造成了预期之外的结果。对于堆破坏的调试的困难之处在于在破坏造成后果的现场通常不是堆被破坏的现场。还好操作系统为我们提供了足够的支持,我们可以使用页堆来尽可能早的发现堆破坏。我们准备如下代码用于调试堆的溢出。
#include <windows.h>#include <stdio.h>#include <conio.h>#define SZ_MAX_LEN 10WCHAR* pszCopy = NULL ;BOOL DupString(WCHAR* psz);void __cdecl wmain (int argc, WCHAR* args[]){ if(argc==2) { wprintf(L"Press any key to start\n"); getchar(); DupString(args[1]); } else { wprintf(L"Please enter a string"); }}BOOL DupString(WCHAR* psz){ BOOL bRet=FALSE; if(psz!=NULL) { pszCopy=(WCHAR*) HeapAlloc(GetProcessHeap(), 0, SZ_MAX_LEN*sizeof(WCHAR)); if(pszCopy) { wcscpy(pszCopy, psz); wprintf(L"Copy of string: %s", pszCopy); HeapFree(GetProcessHeap(), 0, pszCopy); bRet=TRUE; } } return bRet;}开启不完全页堆
通过windbg执行程序:
收到异常消息,并查看出可能出问题的代码的范围:
不完全页堆不能在第一现场中断到调试器,但可以为缩小问题代码的问题提供有利的参考,而完全页堆大部分情况下能够在发生堆破坏的第一现场发出中断:
在程序的开发的整个周期中有必要使用AppVerifier来检验软件的正确性。
0 0
- 堆的调试
- 堆调试
- 调试指南3 堆以及堆上常见的问题
- 常态堆与调试态堆的区别
- 一次堆破坏的调试经历
- 调试堆的一点小收获
- 堆被破坏的调试方法
- 调试堆的一点小收获
- 调试堆的错误-release和debug的差别
- CRT 调试堆
- C++调试堆
- CRT 调试堆
- C++调试堆
- 堆调试利器-Pageheap
- C++调试堆
- C++调试堆
- 堆corruption调试
- 堆损坏异常调试
- MyBatis批量插入数据
- adb常用命令
- Linux系统安装Python PIL模块
- 服务提供者框架示例
- mysql相似于oracle的to_char() to_date()方法
- 堆的调试
- 忽略了导热硅脂等于祸害电脑
- C#数据类型
- JAVASE基础-day15(集合之List集合)
- 【机器学习基础】将回归模型用于分类问题
- Atom 在 linux 下安装有几率侧边栏默认显示在右侧,移动到左侧的设置方法
- [引用区别] c++中引用与java中引用区别 (转)
- Win7 32位 VS2012 不明原因的崩溃
- java实现1到n所有质数