如何检测内存泄露 Topic is solved

这是wxWidgets论坛的中文版本。在这里,您可以用您的母语汉语讨论上面任一子论坛所涉及的所有关于wxWidgets的话题。欢迎大家参与到对有价值的帖子的中英互译工作中来!
Post Reply
Loaden
I live to help wx-kind
I live to help wx-kind
Posts: 177
Joined: Tue Feb 19, 2008 10:21 am
Location: China

如何检测内存泄露

Post by Loaden »

wxWidgets如何检测内存、资源泄露?
用wxWidgets编的程序,在WinXP下,用BoundsChecker检测,发现大量内存泄露与错误!!有点晕!
那么那么多的new都没有对应的delete,感觉在这里很别扭!

各位都是怎么检测有无内存、GDI泄露的?
Life is not fair, get used to it.
Utensil
Moderator
Moderator
Posts: 423
Joined: Sun Feb 03, 2008 11:38 am
Location: China

Post by Utensil »

个人没感觉到wx有内存泄露问题,而且它内部使用了大量的检测技术。一个new不一定literally对应一个delete,不是非得如此才不是泄露。

用BoundsChecker之类的内存泄露检测器常常会出现大量误报,你要正确设置他们才可能把真正的泄露筛选出来。

-Utensil
In fascination of creating worlds by words, and in pursuit of words behind the world.

On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
liuqi5521
Earned some good credits
Earned some good credits
Posts: 103
Joined: Thu Apr 03, 2008 5:35 am
Location: China
Contact:

Post by liuqi5521 »

bounds checker作为一个VC++的插件,主要的使用在IDE中,针对代码检查,这个时候准确性比较高。如果直接用它来查exe文件,我试过,效果并不好,该报告一个也没有报告出来。

wxWidgets本身很少有内存泄露或者访问违例,至少我从未碰到过。内存泄露或访问违例往往发生在自己编写的代码中。其实现在开源的IDE最缺少的就是像VC++下的boundchecker,VA这样的好用的插件,真诚的希望开源的IDE能够集成这些类似的插件!英文好的朋友可以到老外的论坛上呼吁一下。
Loaden
I live to help wx-kind
I live to help wx-kind
Posts: 177
Joined: Tue Feb 19, 2008 10:21 am
Location: China

Post by Loaden »

那如何检测GDI泄露呢?
Life is not fair, get used to it.
liuqi5521
Earned some good credits
Earned some good credits
Posts: 103
Joined: Thu Apr 03, 2008 5:35 am
Location: China
Contact:

Post by liuqi5521 »

想要检测内存泄露最好的方法就是那些集成在IDE中的插件,例如BoundsChecker,和VC++配合得很好。直接对EXE文件检测,难度很高,效果也很不好,目前最有名的IBM purify,也是仅能对VC++编译出的Debug版的EXE实现检测而已,对VC Release版程序都没有效果,更不要说gcc编译出的程序了。

当然IBM purify 有Linux版,对gcc编译出的可执行程序检测,只要编译时带上-g选项即可。

Windows下,对VC++的Release版EXE,或Gcc编译出的Exe,还没有太好的检测工具。当然,你的帖子是在讨论wxWidgets,那么我有一种方法,如果你的平台是Windows,不妨用VC++的编译器来编译wxWidgets,并且编译为Debug版来排错,这个时候,无论是BoundsChecker还是IBM purify,随便你选择哪一个好了。当然,这两个工具都有误报,他们报告的交集,基本上是泄露没错了。个人感觉IBM purify更强大一些,因为它还可以检测所有DLL中的错误。BoundsChecker仅仅检查代码里的错误,程序进到DLL里就不管了,哪怕是DLL释放了内存,它也不知道。
Loaden
I live to help wx-kind
I live to help wx-kind
Posts: 177
Joined: Tue Feb 19, 2008 10:21 am
Location: China

Post by Loaden »

Linux下有哪些手段可以检测内存泄露?
Life is not fair, get used to it.
Utensil
Moderator
Moderator
Posts: 423
Joined: Sun Feb 03, 2008 11:38 am
Location: China

Post by Utensil »

所有使用动态内存分配(dynamic memory allocation)的程序都有机会遇上内存泄露(memory leakage)问题,在Linux里有三种常用工具来检测内存泄露的情況,包括:

1. mtrace
2. dmalloc
3. memwatch


可参见 http://blog.chinaunix.net/u/17855/showart_373394.html
http://www.ibm.com/developerworks/cn/li ... index.html

从原理上分析,这些方法还是会出现大量的误判,因为他们不是基于malloc和free的成对,就是基于new和delete的成对,wxWidgets有自己的new,所以出现误判很正常。我觉得你应该选一两个报错的地方,手工追踪一下,看看是不是真的泄露了。

论坛中有人推荐下面两个工具:

http://valgrind.org/ 基于命令行的

http://sourceforge.net/projects/nvwa/ 基于类库的,你点Summary里的Website,进去可以看到文档和相关的文章。

两个都可以用于Linux下。

-Utensil
In fascination of creating worlds by words, and in pursuit of words behind the world.

On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
Loaden
I live to help wx-kind
I live to help wx-kind
Posts: 177
Joined: Tue Feb 19, 2008 10:21 am
Location: China

Post by Loaden »

发现一个开源的,并且作者是中国人!
http://sourceforge.net/projects/nvwa
Life is not fair, get used to it.
arust
Knows some wx things
Knows some wx things
Posts: 34
Joined: Tue Jan 15, 2008 5:13 am
Location: Beijing, China

Post by arust »

有人用过 wxWidgets 自带的内存检测工具吗?
Cross-Platform GUI Programming with wxWidgets 里面是这样说的:

So how do you know whether your application is leaking memory? Various third-party memory-checking tools are available to do this and more, and wxWidgets has a simple built-in memory checker. To use this checker for your debug configuration, you need to set some switches in setup.h (Windows) or configure (other platforms or GCC on Windows).

On Windows, these are:

#define wxUSE_DEBUG_CONTEXT 1
#define wxUSE_MEMORY_TRACING 1
#define wxUSE_GLOBAL_MEMORY_OPERATORS 1
#define wxUSE_DEBUG_NEW_ALWAYS 1



For configure, pass these switches:

--enable-debug --enable-mem_tracing --enable-debug_cntxt



There are some restrictions to this system: it doesn't work for MinGW or Cygwin (at the time of writing), and you cannot use wxUSE_DEBUG_NEW_ALWAYS if you are using STL in your application or the CodeWarrior compiler.

If wxUSE_DEBUG_NEW_ALWAYS is on, then all instances of the new operator in wxWidgets and your code will be defined to be new(__TFILE__,__LINE__), which has been reimplemented to use custom memory allocation and deletion routines. To use this version of new explicitly, without defining new, use WXDEBUG_NEW where you would normally write new.

The easiest way to use the memory checking system is to do nothing special at all: just run your application in the debugger, quit the application, and see if any memory leaks are reported. Here's an example of a report:

There were memory leaks.

- Memory dump -
.\memcheck.cpp(89): wxBrush at 0xBE44B8, size 12
..\..\src\msw\brush.cpp(233): non-object data at 0xBE55A8, size 44
.\memcheck.cpp(90): wxBitmap at 0xBE5088, size 12
..\..\src\msw\bitmap.cpp(524): non-object data at 0xBE6FB8, size 52
.\memcheck.cpp(93): non-object data at 0xBB8410, size 1000
.\memcheck.cpp(95): non-object data at 0xBE6F58, size 4
.\memcheck.cpp(98): non-object data at 0xBE6EF8, size 8

- Memory statistics -
1 objects of class wxBitmap, total size 12
5 objects of class nonobject, total size 1108
1 objects of class wxBrush, total size 12

Number of object items: 2
Number of non-object items: 5
Total allocated size: 1132



This example tells us that a wxBrush and a wxBitmap were allocated but not freed, along with some other objects whose class is unknown because they do not have wxWidgets type information. In some IDEs, you can double-click on the line with the error and see the source line at which the object was allocated. This functionality is a very good first step in tracking down the cause of the memory leak. For best results, add run-time type information (RTTI) to any classes that are descendants of wxObject. Add DECLARE_CLASS(class) in your class declaration and IMPLEMENT_CLASS(class, parentClass) somewhere in your implementation file.

The memory checking system also tries to catch memory overwrite and double-deletion bugs. The allocation routines write a special signature for a "good" block of memory and another signature for deleted memory. If the application tries to delete a block without the signature, the problem will be reported, as will a deletion that occurs when the block has already been deleted. This will make it easier to catch the kind of memory bugs that only cause problems some time after the real error has occurred.

Using static members of the wxDebugContext class, you can get a listing of the current objects in the system with PrintClasses or show a count of objects and non-objects (those without wxWidgets RTTI information) with PrintStatistics. Using SetCheckpoint, you can tell wxDebugContext to only show statistics from the checkpoint onwards, ignoring memory allocations done prior to this point. For more details, see samples/memcheck and the reference for wxDebugContext.

Instead of using the basic system in wxWidgets, you may want to use a commercial tool such as BoundsChecker, Purify, or AQtime, or a free alternative such as StackWalker, ValGrind, Electric Fence, or MMGR from Fluid Studios. If you are using Visual C++, wxWidgets uses the compiler's standard leak detection, which doesn't report class names but gives you the line numbers. For best results, make sure wxUSE_DEBUG_NEW_ALWAYS is set to 1 in setup.h. Because it redefines new, you might need to disable it if it causes problems with other libraries.
ollydbg23
Super wx Problem Solver
Super wx Problem Solver
Posts: 438
Joined: Fri Dec 12, 2008 10:31 am

Post by ollydbg23 »

Loaden wrote:发现一个开源的,并且作者是中国人!
http://sourceforge.net/projects/nvwa
这个已经很不错了,我已经在使用了。开源世界,不能期望着和VC那样的商业软件做成一样,要不然那帮商业软件怎么混饭吃啊。

另外,codeblocks的代码补全功能,我最近一直在研究,大家有兴趣,可以帮忙改进一下,具体可以看网站上面的wiki和论坛讨论。
Post Reply