勘误和补充
Windows用户态程序高效排错 勘误
===
文章中的疏漏,错误的修正会放在这里。
===
第11页,错误的句子:
问题一共就发生过三次,是通过分析log文件得到的。Log文件记录的是每个时刻Session中的内。
应该修改为:
问题一共就发生过三次,是通过分析log文件得到的。Log文件记录的是每个log生成时刻Session中的内容。
==
如果在VS2005下面想用CRT Debug Heap来调试Memory Leak,最后可以用_CrtDumpMemoryLeaks 把所有的leak打印出来。尝试下面的代码,会怎样:
#include "stdafx.h"
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
#endif
#define MY_NEW[s] new(s,_NORMAL_BLOCK, __FILE__, __LINE__)
#if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
#define new MY_NEW
#endif
int _tmain(int argc, _TCHAR* argv[])
{
char *p=new char[10];
void *p2=malloc(10);
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
#endif
return 0;
}
运行后会看到:
Detected memory leaks!
Dumping objects ->
c:\documents and settings\lixiong\my documents\mycode\detectleak\detectleak\detectleak.cpp(17) : {87} normal block at 0x003A8130, 10 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD
c:\program files\microsoft visual studio 8\vc\include\crtdbg.h(1150) : {86} normal block at 0x003A3240, 10 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[808] DetectLeak.exe: Native' has exited with code 0 (0x0).
注意这里打印出的第一个leak,出现在detectleak.cpp的17行,对应的是malloc语句,没问题
可是第二个leak,出现在crtdbg.h的1150行,而不是new char[10]那里,怎么回事?如果不能定位到正确的源代码,还有什么用呢?
为了搞清楚这个问题,可以看看malloc在debug heap下的的定义:
#ifdef _CRTDBG_MAP_ALLOC
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
注意看,这里用了__FILE__, __LINE__两个预处理器Directive:
The #line Directive
https://msdn2.microsoft.com/en-us/library/b5w2czay.aspx
由于与处理器自动把文件名和行号传递给了_malloc_dbg函数,最后的output窗口才可以打印出源代码行
那好,看看debug heap的new的定义。由于new是C++的关键字,而且是一个操作符,所以debug heap下定义为:
inline __bcount(_Size) void* __CRTDECL operator new[](size_t _Size)
{ return ::operator new[](_Size, _NORMAL_BLOCK, __FILE__, __LINE__); }
注意这里没有用#define,而是inline。同时该定义是在crtdbg.h文件中的。所以最后得到的是文件名是crtdbg.h。你可能有如下疑问:
1. 为什么不用#define而要用inline呢,改成#define可以吗?
你试试看吧,看能不能该成#define。由于这里有一个中括号,麻烦来了吧。谁让你是C++呢?bs一下C++
2. 为什么预处理器看到inline函数,不把inline后的行号和文件名字作为解释呢?
这我就不确定了啦。不过根据C++标准,标示为inline函数不是一定就要inline的,人家标准就定义得模棱两可,你何必强求预处理器呢?
所以,解决方法就是,所有的内存分配,就用:
#ifdef _CRTDBG_MAP_ALLOC
char *test=(char*)::operator new[](20, _NORMAL_BLOCK, __FILE__, __LINE__);
#else
char *test=new char[20];
#endif
你有其它好方法吗?
Comments
- Anonymous
August 15, 2006
English Introduction about the paper and the blog.
欢迎访问。本blog是 《Windows用户态程序高效排错》文章的发布,反馈站点。关于文章的介绍和相关信息,请参考下面对应链接:...