[c++] Windows下VC++ 如何捕捉AllocSysString产生的leak?

103 views
Skip to first unread message

sagasw

unread,
Feb 23, 2010, 10:25:18 PM2/23/10
to pongba
实验代码如下:

USES_CONVERSION;

    CComVariant varStr = "This is string test";

    WCHAR buff[] = L"aaaaaaaaaaaaabbbbbbbbbbbbbbbbb22222222222222222222222222222222222";
   
    CHAR buff2[] = "aaaaaaaaaaaaabbbbbbbbbbbbbbbbb2222222222222222222aaaaaaaaaaaaabbbb222222222222222";

    for (int i = 0; i< 500; i++)
    {
        // will increase memory fastly.
        //varStr.bstrVal = SysAllocString(buff);

        // will crash very soon.
        //varStr.bstrVal = SysAllocString(A2OLE(buff2));

        // will increase memory fastly.
        CString str = buff2;

        //varStr.bstrVal = str.AllocSysString();

        BSTR bstr = str.AllocSysString();
       
        Sleep(1);

        //SysFreeString(bstr);
        ::OutputDebugString("\nloooooooooop\n");
    }

这里产生的Leak无法用CRT方式抓到,实验了visual leak detector http://sites.google.com/site/dmoulding/vld
也在初始化加了如下代码:
    _CrtDumpMemoryLeaks();
    _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

也添加了ONNOCACHE = 1这个全局环境变量

对于new char[255]这种leak都可以在output中输出。

但是这种AllocSysString产生的leak没看到输出。

我用了Debug Diag Tool,
http://www.microsoft.com/downloadS/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en
可以看到如下结果:
Function details
Function   test1!Ctest1Dlg::OnBnClickedButton1+114
Allocation type   BSTR allocation(s)
Allocation Count   5 allocation(s)
Allocation Size   47.86 KBytes
Leak Probability   43%

问题是,还有没有其他工具也可以捕捉到这类leak?或者VC有没有内置的方案,类似CrtDumpMemoryLeaks这样的
不要purify,boundschecker这种重型工具(不想用盗版)。
谢谢。

参考链接:
http://stackoverflow.com/questions/45627/how-do-you-detect-avoid-memory-leaks-in-your-unmanaged-code

------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------

yichen wang

unread,
Feb 23, 2010, 10:40:32 PM2/23/10
to pon...@googlegroups.com
CString是MFC提供的功能,MFC在CRT之上又增加了一层的内存管理。

你可以尝试打开MFC的内存检查,可以参看MSND的“Memory Leak Detection in MFC”,我相信应该会抓到这个问题。

2010/2/24 sagasw <sag...@gmail.com>



--
Stay Hungry. Stay Foolish.

Fuzhou Chen

unread,
Feb 23, 2010, 11:51:02 PM2/23/10
to pon...@googlegroups.com
我印象里MFC的CMemState应该是主要用来track new/delete的,SysAllocString()
管不到。
 
刚才验证了一下,下面这段代码在VS2008是检测不出leak的。很有意思的是,如果我
把这句 oldMemState.Checkpoint() 搬到 CString cStr = L"This is a string!"; 之前,
则无论有没有注释SysFreeString()都会报告泄漏——换句话说,明显的误报了。这
和我的印象是一致的。
 
 
通常我们公司里这种问题主要靠静态分析工具解决。DebugDiag工具的一个问题是64位
下没有debug功能,只能分析,所以对我这边来说很不方便的。这几天有空了再研究研究
如有同学有所发现,请不吝赐教。
 
=== 代码 ===
 
static void DoMyStuff()
{
 AfxEnableMemoryTracking(TRUE);
 CMemoryState oldMemState, newMemState, diffMemState;
 BSTR bstrLeakString = NULL;
 CString cStr = L"This is a string!";
 oldMemState.Checkpoint();
 for (int i = 0; i < 1000; ++i)
 {
  bstrLeakString = cStr.AllocSysString();
  // ::SysFreeString(bstrLeakString);
 }
 newMemState.Checkpoint();
 if (diffMemState.Difference(oldMemState, newMemState))
 {
  ::MessageBox(NULL, L"Leak!", L"Leak!", MB_OK);
  diffMemState.DumpStatistics();
 }
 AfxEnableMemoryTracking(FALSE);
}

 
2010/2/23 yichen wang <wangyic...@gmail.com>



--
《采莲》·江南

为卿采莲兮涉水,为卿夺旗兮长战。为卿遥望兮辞宫阙,为卿白发兮缓缓歌。

另抄自蒜头的评论:http://www.douban.com/review/1573456/

  且祭一束紫琳秋,为一段落花流水的传说
  且饮一杯青花酒,为一场几多擦肩的错过
  且焚一卷旖旎念,为一腔抛付虚无的惜怜
  且歌一曲罢箜篌,为一刻良辰春宵的寂寞

sagasw

unread,
Feb 23, 2010, 11:52:44 PM2/23/10
to pon...@googlegroups.com
试了,没有用。


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2010/2/24 yichen wang <wangyic...@gmail.com>

yichen wang

unread,
Feb 24, 2010, 1:18:45 AM2/24/10
to pon...@googlegroups.com
恩,是我想当然了。

刚才看了一下MFC里的代码,上面的调用最终会进入到ATL.ChTraitsCRT.AllocSysString,实际的内存分配是通过BSTR bstr = ::SysAllocStringLen( NULL, nLen );

5D1B92B5  mov         edx,dword ptr [nLen]
5D1B92B8  push        edx 
5D1B92B9  push        0   
5D1B92BB  call        dword ptr [__imp__SysAllocStringLen@8 (5D5848B8h)]
5D1B92C1  mov         dword ptr [bstr],eax

根据MSDN,SysAllocStringLen是COM系统的内存函数,当前的机器没有Windows系统的symbol,看不到里面。如果CRT不汇报这是memory leak,说明它不是走crt来分配的内存。这个在游戏开发中很普遍。一般都通过Virtual Memory function来分配4K对齐页,然后自己管理。这个时候这个内存对crt来说是透明的,它完全不知道它的存在。因此就不会报告leak了。

查这种问题一般要借助外部工具了,你看看你手头的工具有没有可以跟踪COM的。此外,MS Debug Tools里有一个User-Mode Dump Heap工具,可以用来追踪这种问题。UMDH用来对付你这个sample是足够且高效的,不过对于那种内存占用500M以上,分配释放很频繁的软件,要找到真正的leak就很难了。



2010/2/24 sagasw <sag...@gmail.com>

Dbger

unread,
Feb 24, 2010, 10:58:42 AM2/24/10
to pon...@googlegroups.com
 SysAlloc**这样的函数内存是分配在COM自己的堆上的。
根据这篇文章,LeakDiag应该是你要找的工具,你可以试试: download


技术博客:http://debuggingnow.com
我的豆瓣:http://www.douban.com/people/baiyanhuang/


2010/2/24 yichen wang <wangyic...@gmail.com>

Zhiming G

unread,
Feb 24, 2010, 11:12:46 AM2/24/10
to pon...@googlegroups.com
再补充几个, 可能会用的上: 
BoundsChecker
HeapAgent
Purify NT
Google Heap Checker

Fuzhou Chen

unread,
Feb 24, 2010, 4:45:34 PM2/24/10
to pon...@googlegroups.com
昨晚上做了点试验,大概是这么个结果:


首先,对于COM内存泄漏的问题,UMDH不是一个好的方案。原因有二:

a) UMDH的主要作用是处理系统堆,也就是通过HeapAlloc()得到的
 内存的泄漏问题。COM显然是有自己的堆管理的,因为它支持Marshall和线程
内存Apartment模型,这个功能系统堆和CRT堆都没有提供。

b) 从实践上讲,UMDH的检查方式是通过比较两次快照来得到堆内存使用情况的,
如果没有确认一个大概的造成泄漏的代码区间,那么UMDH的检查无异于大海
捞针,工作效率不高。至少在我的实验里,UMDH没有抓到100次的泄漏。

第二,能够管用的工具:微软的DebugDiag,不过我自己没有成功抓到我的代码
里的leak。如果Sagasw方便的话,可否大概贴出一个步骤?


第三,API级别的方案是有的,不过很麻烦。对于特定于COM的内存调试,可以通
过注册一个实现了IMallocSpy的调试对象来做到。

http://msdn.microsoft.com/en-us/library/ms688508(VS.85).aspx

通过这个Object,我们可以在每一次实际分配内存的时候人为地添加一个cookie,主
要是通过IMallocSpy::PreAlloc()将需要分配内存的大小改大一点,比如8byte,然后在
IMallocSpy::PostAlloc()里可以操作那块多出来的内存,作为一个cookie来保存内存地
址之类的信息,以供最后比较。

关于IMallocSpy,有一个不错的例子:http://comcorba.tripod.com/comleaks.htm。我
自己也写了一个例子,不过时间所限,做得非常简陋,这个例子比我的强很多,推荐参
考。

但这个方案一样存在大海捞针的风险,因为IMallocSpy是作用于整个COM runtime,
所以中间可能会记录大量正常的分配/释放操作,不利于快速缩小怀疑范围。

我知道Windows支持对单个进程打开User Mode栈回溯,所以有一种思路是配合栈回
溯在每一次分配时打印出栈信息。可惜我最近也才刚刚进入这个领域,手头没有一个
现成的例子,如果有高手的话不吝赐教。

2010/2/24 Zhiming G <gao...@gmail.com>

--

sagasw

unread,
Feb 24, 2010, 7:44:05 PM2/24/10
to pon...@googlegroups.com
LeakDiag好像能用,但是感觉不是一个可用的方案,没有官方发布,没有进一步的支持,甚至域名都是ftp开头,谁见过微软这样发布过什么正式一点的软件么?

我回家以后也做了一些搜索,感觉如果是比较严重的leak,可以oldnewthing提供的办法来验证。
一般defect关心的leak不会是几十几百k的,而是跑overnight会增长到十几几十M一级内存泄露。
Oldnewthing在“The poor man's way of identifying memory leaks"提到一个不算是办法的办法,just let leak happen。
http://blogs.msdn.com/oldnewthing/archive/2005/08/15/451752.aspx
当泄露大量发生以后,再dump出内存,这时候里面一定会有超多的不应该在那里的对象尸体。
你就可以大胆的说:”哦,原来你也在这里“,怎么分析就是看你的功力了,我进一步的建议是对于可能存在泄露的对象,加上一个类似m_classname的字符串成员,写上一个好辨认的名字,查找起来更容易,吼吼。

Fuzhou Chen说抓不到泄露,最大的可能是ONNOCACHE没有设置为1(这会让操作系统对BSTR做缓存),如果是的话,找一下msdn或者我的博客都有介绍。注意设置以后要重启。

BTW,在这里插一句,缓存系统会让运行性能提高,但是也会带来非常大的副作用,比如代码复杂化,程序运行不确定,或者类似的leak无法找到之类。要小心使用。

除了实现IMalloc,我想到的方案是用global system hook的方式,看看是不是能抓到系统的调用。另外可以用微软的detour来试验,现在只是个构想,我们这种低水平开发公司暂时用不到的,吼吼。

我其实关注的是,比如有些写法会造成某个对象的泄露,但不是大量泄漏,类似SysAllocString这种CRT抓不到的,只能用肉眼看(code review的重要性体现出来了),然后判断是否有泄漏,就是用肉体弥补技术上的不足了,吼吼。

Fuzhou Chen,我的实验过程基本都在这个帖子里,也可参考
http://sunxiunan.com/?p=1546
我用的是VC2010,windowsXP,有问题欢迎回复交流。


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2010/2/25 Fuzhou Chen <cppo...@gmail.com>

Fuzhou Chen

unread,
Feb 24, 2010, 8:58:52 PM2/24/10
to pon...@googlegroups.com
果然,我还真的没有设ONNOCACHE,受教了。最近我在公司里筹备一个关于内存问题的讲座,
正好用上。

如果用Global System Hook,我们公司倒是有内部的工具,不过主要是用来做Fuzzying测
试,而且未免过于重量级。我个人认为IMallocSpy的做法不错,首先它不限于Debug build,其
次cookie的格式可以自己定义,所以它适合做成一个函数库。如果公司产品大量地使用COM而且
产品需要长期运行(比如服务器),那么花些精力写这么一个函数库用来做压力测试,从长远看是
有收益的。


我不喜欢Just Let Leak Happen的主要理由是这个办法只有当Leak已经很大的时候才会容易被人
察觉,而泄漏太多的情况下有三个问题:

a) 如果单次泄漏内存不大,那么当总泄漏量很大的时候往往表示这个软件需要长时间运行,测试
重现可能需要太长的时间。

b) Let it happen的办法不会帮助我们定位。而调试时最耗时间的就是定位,代码大了尤其如此。

c) Let it happen最可怕的是它可能在客户那边才出现。如果泄漏的严重程度已经到了客户气得要
上门骂人,那么这个时候开发方面的压力会非常大。站在团队角度考虑,我宁可花时间写测试
工具也不愿让客户发现这个问题。相信我,我曾经有一个同事一个类似的问题折腾得很惨,幸
亏是handle泄漏,相对容易发现。

2010/2/24 sagasw <sag...@gmail.com>:

yichen wang

unread,
Feb 24, 2010, 9:59:36 PM2/24/10
to pon...@googlegroups.com
类似这种情况,我碰到的常规做法实现一个自己的对于内存管理的包装对象。

在retail版本,它什么都不做,直接把对应的调用pass到系统库即可。在debug/release版本,它都负责做记录/检查/核对的工作。碰到情况复杂的,还可在每次调用时通过dbghelp库抓取当前的call-stack,如果是第一次碰到就保存下来,然后把调用和call-stak的key关联起来。这样重复释放/leak/甚至冲内存都可以定位。

上面你们提到的这种问题,解决三四个问题的时间就可以写出这么一个系统了,能够节省以后海量的时间。

不过仅限于你在调试有源码的系统,对那些做支持的同学表示安慰。

2010/2/25 Fuzhou Chen <cppo...@gmail.com>:

sagasw

unread,
Feb 25, 2010, 1:26:17 AM2/25/10
to pon...@googlegroups.com
能具体说说如何针对BSTR或者AllocSysString这种情况如何包装么?


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2010/2/25 yichen wang <wangyic...@gmail.com>

Fuzhou Chen

unread,
Feb 25, 2010, 3:24:29 AM2/25/10
to pon...@googlegroups.com
同上,我也想知道。


对于CRT的debug,比如MFC的DEBUG_NEW,我能想到的东西就是用自己的
堆管理代替。不过具体到AllocSysString()会有两个问题:

a) AllocSysString()参数包含初始化,所以不能简单地利用宏来修改长度值获得
用于cookie的额外内存。
b) AllocSysString()用的应该是COM的堆。如果我们用我们自己的堆管理系统
代替它,那么在跨Apartment传递字符串的时候就可能造成崩溃。

如果限制绝对不许用IMallocSpy,那么我倒是有一个蠢办法。

我可以不用cookie,而是做WriteLog(),打印出每一次分配释放的__FILE__,
__LINE__以及字符串首地址。这样执行完一遍后再写个脚本,根据字符串首
地址对所有的分配和释放操作进行配对。如果存在泄漏,则必定有些Alloc操
作找不到对应的Free调用。这样的脚本用Perl来写并不困难。


如果我们试图为一个已经存在的项目添加支持,则需要定义SysAllocString和
SysFreeString宏,并要求所有的cxx文件在包含文件列表的最后包含我们的
宏定义(具体见下面的strdbg.h)。这样后面的SysAllocString()和
SysFreeString()才能被替换为我们的debug版本,并且输出log。


我说我的办法蠢的主要原因是它不能替换所有的函数调用。因为别的函数
库,比如MFC,也是会包含OLE的头文件并使用Sys*函数的。如果这些库是以
目标文件的方式连接进来,则这时候这个方案就不具备跟踪能力,除非我们能
够保证我们用的库永远是模板——显然这是不现实的。

另外,如果我们真的想用自己的宏替换第三方模板文件里的Sys*String()函
数,我们也可能必须得用一些奇技淫巧才能成功做到,因为头文件之间的包含
关系本来就很难理顺。这个我没办法展开,因为我确实从来没有用过MFC,所
以不敢夸口,而且过于花巧的方法可能会给以后的阅读理解造成困难。所以
我的建议是最好避开这个问题。


// ==== strdbg.h ====
#ifndef _STRDBG_H_
#define _STRDBG_H_

extern BSTR
_DEBUG_SysAllocString(const OLESTR* oleStr, TCHAR* szFile, DWORD dwLine);
extern VOID
_DEBUG_SysFreeString(const BSTR* bstr, TCHAR* szFile, DWORD dwLine);

#define SysAllocString(str) __DEBUG_SysAllocString(str, __FILE__, __LINE__)
#define SysFreeString(str) __DEBUG_SysFreeString(str, __FILE__, __LINE__)

#endif /* End of strdbg.h */

// ==== strdbg.cxx ====
// XXX Warning: NEVER include strdbg.h
#include <atlbase.h>

BSTR
_DEBUG_SysAllocString(const OLESTR* oleStr, TCHAR* szFile, DWORD dwLine)
{
BSTR* newStr = ::SysAllocString(oleStr);
WriteSomeLog(L"[A]%u, %s, %d", oleStr, szFile, dwLine);
return newStr;
}

VOID
_DEBUG_SysFreeString(const BSTR* bstr, TCHAR* szFile, DWORD dwLine);
{
WriteSomeLog(L"[F]%u, %s, %d", oleStr, szFile, dwLine);
::SysFreeString(bstr);
}
// ==================

// ==== YourCode.cxx ====
#include "stdafx.h"
#include "atlbase.h"
#include "XXXX.h"
#include "strdbg.h"

static void DoMyStuff()
{
// Now we will actually call _DEBUG_SysAllocString(), with
__FILE__ and __LINE__
BSTR* bstrMyStr = ::SysAllocString(L"Leak test");
}


2010/2/24 sagasw <sag...@gmail.com>:

yichen wang

unread,
Feb 25, 2010, 3:25:57 AM2/25/10
to pon...@googlegroups.com
我自己没有碰到过需要用AllocSysString的情况,我先描述一下我自己的情况,看看对你有没有帮助。最后我无责任盲想一下如何应对你的问题。

首先就是同一内存分配的出入口,比如实现自己的TLMalloc, TLFree,
TLRealloc类。然后呢,看你有没有合适的利用C++特性来替换new/delete的机会,以Python实现为例,它就能够找到一个足够高的同一父类Object来做这件事情。在自己能够控制的范围内尽可能的统一入口。

当有了自己的入口以后,TLMalloc可以添加‘额外参数来表示来自什么模块,什么特性,对对齐有什么要求,根据不同的用法,可以把性质不同的分配放在不同的区域内。比如所以尺寸小于128字节的放入一个块里,然后128~1024间的在一起,这种内存管理算法的代码很多,可以google,Linux采用的DL
malloc就十分的经典(在用于windows下时候,极端情况会有问题,需要关闭segment合并)。

接下来的就是在中间层里添加管理,记录和检查代码了。

再回来尝试解决你的问题:

#1你如果需要的仅仅是一个普通的String类,那么CString不是好选择,更不是唯一的选择。比如STL或者boost,都提供你替换默认的allocator。用自己的allocator来负责记录/分配。
#2如果你因为某种原因,不能使用外部的/开源的库,或者遗留代码带多的话,自己动手也未尝不可。参考MFC代码,
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
其中StrTraitMFC_DLL就是最终负责分配内存的实现,见前文的ATL.ChTraitsCRT.AllocSysString。实现你自己的TL_CString来替换掉它。这里顺便说句额外的,项目开始的时候定义一下
typedef signed __int8 TL_SBYTE;
typedef signed __int32 TL_INT;
typedef CString TL_String;
都是好习惯,不论是为了开发方便,或者跨平台等等。额外的封装就是剥离。
#3不论什么办法,开发人员自己注意永远是最重要的。参考我说的John的那本调试的书,他举了一个他自己的例子,有一个公司碰到menory
问题,全项目全部停下来查了很多久都没有搞定,产品严重延期,花钱请他查(他单干前,在一个很出名的内存检查工具公司,名字我记不起来了),他要求说派两个新的不能再新的新人给他帮忙,公司说,我们有很资深的程序员可以帮你,他说不要,他们对系统太了解,成见太深了。一开始,他让这个两个程序员帮他一起把所有的未初始化的指针都初始化,就是int
*p=null然后,,,,问题就解决了。一句话,要当心。我不知道有哪些强力的工具,不知道有没有工具(非静态分析)可以查到下面的问题,求工具达人指点。
{
LPVOID *p = VirtualAlloc(...., 4096,.....);
}

大致就这样吧。

顺便给这个我很稀饭的大牛做个广告:
http://www.wintellect.com/
The company was founded in spring 2000 by three developers — Jeff
Prosise, Jeffrey Richter, and John Robbins — and businessman Lewis
Frazer.
他们的Instructors名单里更是大牛云集,哈哈。

2010/2/25 sagasw <sag...@gmail.com>:

机械唯物主义 : linjunhalida

unread,
Feb 25, 2010, 3:30:15 AM2/25/10
to pon...@googlegroups.com
我已经对通过调试来debug这条路子不报希望了。。

每个模块弄得清晰,加注释,作单元测试,加log,assert。。。。这套路子还靠谱些。
代码能不写就不写,考虑工作量的时候把调试成本加上去。。。。

2010/2/25 yichen wang <wangyic...@gmail.com>

Fuzhou Chen

unread,
Feb 25, 2010, 3:38:47 AM2/25/10
to pon...@googlegroups.com
对于新代码而言,这条路确实更靠谱;不过这世上老代码多了去了,
事到临头时总有必须调试的时候。何况万恶的商业总能给你整出
无数的理由让你不能看代码、不能现场调试……总归什么都不能。

说得难听一点,大家都是出来混碗饭吃的,遇到问题就撂挑子是很
潇洒,可家里的老婆孩子还等着要这份工资呢。。

所以结论就如同黑格尔的话:凡是现实的都是合理的。适当掌握
一些调试的技巧是必须的。

2010/2/25 机械唯物主义 : linjunhalida <linjun...@gmail.com>:

yichen wang

unread,
Feb 25, 2010, 3:42:35 AM2/25/10
to pon...@googlegroups.com
兄弟,到这里,我诚恳的说,你说的是对的,都对,包括另外一个邮件里的。

2010/2/25 Fuzhou Chen <cppo...@gmail.com>:

Fuzhou Chen

unread,
Feb 25, 2010, 3:58:24 AM2/25/10
to pon...@googlegroups.com
呵呵不用这么郑重吧。都是有感而发而已。论坛上都是坐而论道,求的又不是
输赢。

其实我倒是很好奇那个VirtualAlloc(...., 4096, ....)的问题。我工作里的主力
用LocalAlloc和COM,一般不允许直接用VirtualAlloc(),莫非和4K字节对齐
有关,或者是因为忘记VirtualFree()导致内存泄漏?

另外,你说的那个John Robbins大牛参加过的很有名的静态软件检查工具
公司,莫非指的是Coverity(http://www.coverity.com)?


我这边快一点了,先睡。

2010/2/25 yichen wang <wangyic...@gmail.com>:

yichen wang

unread,
Feb 25, 2010, 4:41:19 AM2/25/10
to pon...@googlegroups.com
也不是输赢,我怕你误会我的态度^_^。

至于说LPVOID *p = VirtualAlloc(....,
4096,.....);是因为我在看Microsoft.Windows.Internals
5e,里面对于进程创建过程的描述让我觉得几乎没有办法在virtual memory page
层面上分辨什么是leak,什么是不是。在其他工具或者CRT有机会介入前系统已经在虚拟内存页表里添加大量的信息了,而且这张表本身是不断变动的,虚地址到物理地址的变化经常会变,如何指正某一个是leak呢?

说到这里,实际上在VirtualAlloc继续向下走,会进入到很多Rtl开头的函数,名字上看是辅助作用的,也许微软会在某个层次上开放一个接口来专供调试用。我没有怎么留意内存调试工具,所以问问你们。

2010/2/25 Fuzhou Chen <cppo...@gmail.com>:

Fuzhou Chen

unread,
Feb 25, 2010, 7:47:25 PM2/25/10
to pon...@googlegroups.com
我的看法是如果搞用户态应用,那么就不该试图直接定位物理内存。Rtl系列函数已经是DDK
提供的API,一般情况下写个服务时我是不敢随便碰的。

所以我也就是胡猜,这个时候用我那个蠢办法,配合打印虚拟地址,也许还可靠一点?

2010/2/25 yichen wang <wangyic...@gmail.com>:

John Lan

unread,
Feb 26, 2010, 12:07:19 PM2/26/10
to pon...@googlegroups.com
debugdiag 支持上面列出的所有allocator, 包括SysAllocStringXxx,VirtualAlloc, 而且,MS
不出意外应该会持续update这个工具。

2010/2/26 Fuzhou Chen <cppo...@gmail.com>:


> 我的看法是如果搞用户态应用,那么就不该试图直接定位物理内存。Rtl系列函数已经是DDK
> 提供的API,一般情况下写个服务时我是不敢随便碰的。
>
> 所以我也就是胡猜,这个时候用我那个蠢办法,配合打印虚拟地址,也许还可靠一点?
>
> 2010/2/25 yichen wang <wangyic...@gmail.com>:
>> 也不是输赢,我怕你误会我的态度^_^。
>>
>> 至于说LPVOID *p = VirtualAlloc(....,
>> 4096,.....);是因为我在看Microsoft.Windows.Internals
>> 5e,里面对于进程创建过程的描述让我觉得几乎没有办法在virtual memory page
>> 层面上分辨什么是leak,什么是不是。在其他工具或者CRT有机会介入前系统已经在虚拟内存页表里添加大量的信息了,而且这张表本身是不断变动的,虚地址到物理地址的变化经常会变,如何指正某一个是leak呢?
>>
>> 说到这里,实际上在VirtualAlloc继续向下走,会进入到很多Rtl开头的函数,名字上看是辅助作用的,也许微软会在某个层次上开放一个接口来专供调试用。我没有怎么留意内存调试工具,所以问问你们。
>>
>> 2010/2/25 Fuzhou Chen <cppo...@gmail.com>:
>>> 呵呵不用这么郑重吧。都是有感而发而已。论坛上都是坐而论道,求的又不是
>>> 输赢。
>>>
>>> 其实我倒是很好奇那个VirtualAlloc(...., 4096, ....)的问题。我工作里的主力
>>> 用LocalAlloc和COM,一般不允许直接用VirtualAlloc(),莫非和4K字节对齐
>>> 有关,或者是因为忘记VirtualFree()导致内存泄漏?
>>>
>>> 另外,你说的那个John Robbins大牛参加过的很有名的静态软件检查工具
>>> 公司,莫非指的是Coverity(http://www.coverity.com)?
>>>
>>>
>>> 我这边快一点了,先睡。
>>>
>>> 2010/2/25 yichen wang <wangyic...@gmail.com>:
>>>> 兄弟,到这里,我诚恳的说,你说的是对的,都对,包括另外一个邮件里的。
>>>>
>>>> 2010/2/25 Fuzhou Chen <cppo...@gmail.com>:
>>>>> 对于新代码而言,这条路确实更靠谱;不过这世上老代码多了去了,
>>>>> 事到临头时总有必须调试的时候。何况万恶的商业总能给你整出

>>>>> 无数的理由让你不能看代码、不能现场调试......总归什么都不能。

>>>>>>> The company was founded in spring 2000 by three developers -- Jeff
>>>>>>> Prosise, Jeffrey Richter, and John Robbins -- and businessman Lewis

John Lan

unread,
Feb 26, 2010, 12:23:30 PM2/26/10
to pon...@googlegroups.com
另外关于SysAllocString的内部一些东西,大家如果感兴趣可以读一下
<Heap Feng Shui in JavaScript>, google 可以搜到。

2010/2/27 John Lan <lan....@gmail.com>:

Reply all
Reply to author
Forward
0 new messages