调试内存泄漏

扫码查看
本文介绍了调试内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好!

我做了一小段代码,我觉得这对调试非常有用,

我想问你是否正确,不知怎么可以接受或者如果我

只是重新发明轮子。

为了处理因内存泄漏导致的一些不良错误我最终得到了这个简单的解决方案:我制作了一个头文件,当包含时,将malloc / calloc / realloc / free函数替换为一些其他函数

执行实际作业并插入(或删除)在列表中指向

已分配内存的指针。通过这种方式,我可以捕获许多错误,因为双重释放,零大小的分配或缺少免费调用。

显然只有在设置了给定的#define时它才有效( NDEBUG,在我的

案例中。

你怎么看?

提前谢谢你!

(如果你想看到我在这里写了一个小页面的代码:

Hello!
I made a short piece of code that I find very useful for debugging,
and I wanted to ask you if it is correct, somehow acceptable or if I
simply reinvented the wheel.
To deal with some bad bugs caused by memory leaks I ended up with this
simple solution: I made one header file that, when included, replaces
the malloc/calloc/realloc/free functions with some other functions
that do the actual job and insert (or remove) the pointers to the
allocated memory in a list. This way I can catch many errors as double
frees, allocations of zero size, or missing calls to free.
Obviously it works only when a given #define is set (NDEBUG, in my
case).
What do you think about it?
Thank you in advance!
(If you want to see the code I wrote a little page here:
http://technicalinsanity.org/out/simplegc/index.html)

推荐答案



你已经重新发明了轮子。类似于调试内存泄漏,许多程序员已经完成了

。 (这并没有减少

这样做很有用。)

-

Ben Pfaff




NDEBUG通常是#define'来表示你不想调试

功能在代码中打开。所以,如果我正确理解你

并且你用它打开调试malloc系列

替换,那可能不是那么好想法。


除此之外,听起来你已经重新发明了一个特别有用的

轮;如果你还没有那么大的轮子和承重 -

ness,你的版本可能会很好。


< OT> ;

我Mac上的标准库malloc支持您描述的大部分检查

功能,并允许通过设置

打开它们运行程序之前适当的环境变量。我强烈怀疑这是继承自FreeBSD的,如果其他BSD有类似的调试支持,那就不会感到惊讶。


如果您正在使用Linux / x86,那么您应该看看Valgrind,它可以完成所有这些以及更多。

< / OT>


请注意,通过替换malloc和朋友,你违反了合同

,C语言的定义指定了你和

编译器的实现者;你可能会通过这样做打破一些东西



(为了调试内存问题,这可能是可以接受的。最差的

可能发生的事情是你以一种干扰你调试的方式破坏事物,甚至在这种情况下恢复到非malloc-

调试版本会让你回到你开始的地方,而你所失去的一切

就是你所希望的更远一点。)


如果你避风港它们已经实现了它们(我没有查看你的代码),

你们也可能会发现一些有用的包装宏:

------ -

#undef malloc

#define malloc(sz)my_malloc(sz,__ FILE __,__ LINE__)

#undef free

#define free(ptr)my_free(ptr,__ FILE __,__ LINE__)

#undef realloc

#define realloc(ptr,sz)my_realloc(ptr,sz) ,__ FILE __,__ LINE__)

#undef calloc

#define calloc(num,sz)my_calloc(n嗯,sz,__ FILE __,__ LINE__)

--------

这允许你的调试版本(需要带文件名

和行参数,当然)跟踪他们从

调用的位置,并在他们发现问题时报告。

dave


-

爱斯基摩网上的Dave Vandervies dj3vande com

你可以通过编造一些结果来节省很多工作;

如果你实际进行了

调查,他们会和你得到的一样好。 --Eric Sosman in comp.lang.c

NDEBUG is usually #define''d to indicate that you DON''T want debugging
features turned on in the code. So if I''m understanding you correctly
and you''re using it to turn on your debugging malloc family
replacement, that''s probably Not Such A Good Idea.

Other than that, it sounds like you''ve reinvented a particularly useful
wheel; if you don''t already have a wheel of that size and load-bearing-
ness, your version will probably do fine.

<OT>
The standard library malloc on my Mac supports most of the checking
features you describe, and allows them to be turned on by setting
appropriate environment variables before running the program. I
strongly suspect that this was inherited from FreeBSD, and would be
unsurprised if other BSDs have similar debugging support.

If you''re using Linux/x86, you should take a look at Valgrind, which
can do all of that and more.
</OT>

Note that by replacing malloc and friends, you''re breaking the contract
that the definition of the C language specifies between you and the
implementor of your compiler; it''s possible that you''ll break something
by doing this.
(For debugging memory problems, this is probably acceptable. The worst
that can happen is that you break things in a way that interferes with
your debugging, and even in that case reverting to the non-malloc-
debugging build will leave you back where you started, and all you lose
is the getting a little bit farther ahead that you were hoping for.)

If you haven''t already implemented them (I didn''t look at your code),
you might also find a few wrapper macros useful:
--------
#undef malloc
#define malloc(sz) my_malloc(sz,__FILE__,__LINE__)
#undef free
#define free(ptr) my_free(ptr,__FILE__,__LINE__)
#undef realloc
#define realloc(ptr,sz) my_realloc(ptr,sz,__FILE__,__LINE__)
#undef calloc
#define calloc(num,sz) my_calloc(num,sz,__FILE__,__LINE__)
--------
This allows your debugging versions (which will need to take filename
and line arguments, of course) to track where they were called from
and report that when they detect problems.
dave

--
Dave Vandervies dj3vande at eskimo dot com
You can save yourself a lot of work by just making up some results;
they''ll be just as good as those you''d get if you actually ran the
survey. --Eric Sosman in comp.lang.c




按照惯例,像gc_need_real这样的宏应该都是大写的。

当然,这只是一个约定,但是很有用一。如果它是

#defined,你应该记住,可能已经有使用你使用的相同名称定义的标准

库宏。在用自己的替换之前,你应该#undef

任何这样的定义。在

原则中,如果gc_need_real是#defined,那么调用普通malloc()系列的任何程序

的行为都是未定义的。在实践中,

替换标准库函数通常是有效的,并且是一种执行内存泄漏检查的流行方法。


请记住,您的方法完全没用

调查由于直接调用

malloc()系列而导致的内存泄漏,这些系列是在不使用您的

头文件。


你是否正确地重新发明

轮是完全正确的。您应该检查您的实现是否提供了

malloc()系列的调试版本。如果提供的是
,那么使用它可能比您自己的更换更安全。另外,

这种相同的技术被大量的内存泄漏测试使用

包,其中一些比你能做的任何东西都复杂得多

容易写。在这两种情况下,替换库函数

实际上替换了正常的标准库函数,而不是包装它们的
。因此,您甚至可以检测在不使用头文件的情况下编译的库中发生的内存泄漏。

By convention, macros such as gc_need_real should be all upper-case.
Of course, this is only a convention, but a useful one. If it is
#defined, you should keep in mind that there may already be standard
library macros defined with the same names you use. You should #undef
any such definitions before replacing them with your own. In
principle, if gc_need_real is #defined, the behavior of any program
which calls the normal malloc() familiy is undefined. In practice,
replacement of standard library functions often works, and is a
popular method of performing memory leak checks.

Keep in mind that your approach is completely useless for
investigating memory leaks that are due to direct calls to the
malloc() family from libraries that were built without using your
header files.

You are quite right to worry about whether you are "reinventing the
wheel". You should check to see whether a debugging version of the
malloc() family is provided by your implementation. If one is
provided, it''s probably safer to use than your own replacement. Also,
this same technique is used by a number of memory leak testing
packages, some of them much more sophisticated than anything you could
easily write. In both cases, the replacement library functions
actually replace the normal standard library functions, rather than
wrapping them. As a result, you can even detect memory leaks that
occur in libraries that were compiled without using your header file.


这篇关于调试内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 17:32
查看更多