每当调用 malloc/free 时输出到 stderr
对于 Linux/GCC/C++,我想在调用 malloc/free/new/delete 时向 stderr 记录一些内容。 我试图了解库的内存分配,因此我想在运行单元测试时生成此输出。 我使用 valgrind 进行内存泄漏检测,但我找不到使其仅记录分配的选项。
有任何想法吗? 我正在寻找最简单的解决方案。 重新编译库不是一个选项。
With Linux/GCC/C++, I'd like to record something to stderr whenever malloc/free/new/delete are called. I'm trying to understand a library's memory allocations, and so I'd like to generate this output while I'm running unit tests. I use valgrind for mem leak detection, but I can't find an option to make it just log allocations.
Any ideas? I'm looking for the simplest possible solution. Recompiling the library is not an option.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用 ltrace 跟踪对 malloc/free 的调用:
要在不重新编译的情况下跟踪新的/删除的调用,您可能需要使用 LD_PRELOAD 之类的东西来用您自己的版本覆盖调用,这正是 LeakTracer 可以实现您想要的功能。
You can trace calls to malloc/free with ltrace:
To trace new/delete calls without recompiling you will probably need to use something like LD_PRELOAD to override the calls with your own versions, this is precisely what LeakTracer does which might do what you want.
本文(向下滚动到底部)提供关于如何在 C++ 中重写全局
new
和delete
运算符的非常清晰简洁的描述(请注意,它没有提供new[]< /code>,但概念相似)。
至于覆盖 malloc 和 free,由于您使用的是 Linux 和 GCC,最简单的方法是使用
malloc_hook
和free_hook
。 这里很好地描述了这些函数的工作原理。This article (scroll down to the bottom) provides a very clear and concise description of how to override the global
new
anddelete
operators in C++ (note that it doesn't provide an example fornew[]
, but it's similar in concept).As far as overriding malloc and free, since you're working on Linux and with GCC, the easiest method is to use
malloc_hook
andfree_hook
. Here is a very good description of how these functions work.malloc_hook(3)
允许您全局插入自己的malloc
函数。 (还有__realloc_hook
__free_hook
等,为了简单起见,我只是将它们排除在外。)printf
可能会调用malloc,这就是我们暂时撤消钩子的原因。 如果您以任何方式挂接
malloc
,请小心这一点。malloc_hook(3)
allows you to globally interpose your ownmalloc
function. (There's__realloc_hook
__free_hook
etc. as well, I've just left them out for simplicity.)printf
might callmalloc
, which is why we undo the hook temporarily. Be careful of this if when you hookmalloc
in any way.我自己没有测试过这个,但我很确定这些会起作用:
由于您不想重新编译库,因此给出有意义的输出(相对于仅“新调用 23 字节”)可能需要获取堆栈跟踪。 我记得使用函数来导航堆栈,但现在找不到它们。 也许调用 system() 和 pstack(1) 可以解决这个问题。
您可以重新定义operator new和delete,并将这个新定义放在std c++库之前。 这可能无法捕获来自相关库正在使用的容器和标准组件的调用。 这需要重新链接。
使用可以使用LD_PRELOAD来动态改变operator new和delete。 如果您的应用程序是动态链接的,则不需要重新链接。
希望这些建议有所帮助,很抱歉我没有食谱。
I have not tested this myself, but I am pretty sure these would work:
Since you do not want to re-compile the library, giving meaningful output (vs. just "new called for 23 bytes") may require getting a stack trace. I remember using functions to navigate the stack, but I cannot find them right now. Maybe a call to system() and pstack(1) can do the trick.
You can re-define operator new and delete, and put this new definition ahead of the std c++ library. This may not capture the calls from containers and standard components that the library in question is using. This would require a relink.
Use can use LD_PRELOAD to change operator new and delete dynamically. This would not require a re-link if your application is dynamically linked.
Hope these pointers help, I am sorry I do not have a recipe.