勘误和补充


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.cpp17行,对应的是malloc语句,没问题


可是第二个leak,出现在crtdbg.h1150行,而不是new char[10]那里,怎么回事?如果不能定位到正确的源代码,还有什么用呢?


 


为了搞清楚这个问题,可以看看mallocdebug heap下的的定义:


 


#ifdef  _CRTDBG_MAP_ALLOC


 


#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)


 


注意看,这里用了__FILE__, __LINE__两个预处理器Directive:


 


The #line Directive 
http://msdn2.microsoft.com/en-us/library/b5w2czay.aspx


 


由于与处理器自动把文件名和行号传递给了_malloc_dbg函数,最后的output窗口才可以打印出源代码行


 


那好,看看debug heapnew的定义。由于newC++的关键字,而且是一个操作符,所以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 (1)

  1. English Introduction about the paper and the blog.

    欢迎访问。本blog是 《Windows用户态程序高效排错》文章的发布,反馈站点。关于文章的介绍和相关信息,请参考下面对应链接:…

Skip to main content