我如何在 OS X 下覆盖 malloc()、calloc()、free() 等?
假设使用最新的 XCode 和 GCC,覆盖内存分配函数的正确方法是什么(我猜也是 new/delete 运算符)。 调试内存分配器对于游戏来说太慢了,我只需要一些基本的统计数据,我可以自己做,影响最小。
由于钩子,我知道它在 Linux 中很容易,十年前当我编写 HeapManager 时,这在 codewarrior 下是微不足道的。
遗憾的是 smartheap 不再有 mac 版本。
Assuming the latest XCode and GCC, what is the proper way to override the memory allocation functions (I guess operator new/delete as well). The debugging memory allocators are too slow for a game, I just need some basic stats I can do myself with minimal impact.
I know its easy in Linux due to the hooks, and this was trivial under codewarrior ten years ago when I wrote HeapManager.
Sadly smartheap no longer has a mac version.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我将使用库预加载来完成此任务,因为它不需要修改正在运行的程序。 如果您熟悉执行此操作的常用 Unix 方法,那么几乎只需将 LD_PRELOAD 替换为 DYLD_INSERT_LIBRARIES 即可。
第一步是使用此类代码创建一个库,然后使用常规共享库链接选项 (
gcc -dynamiclib
) 构建它:请注意,如果您还转移
calloc()
及其实现调用malloc()
,您可能需要额外的代码来检查您的调用方式。 C++ 程序应该非常安全,因为new
运算符无论如何都会调用malloc()
,但请注意,没有标准强制执行这一点。 不过,我从未遇到过不使用malloc()
的实现。最后,为您的程序设置运行环境并启动它(可能需要根据您的 shell 处理环境变量的方式进行调整):
请参阅 dyld 手册页 了解有关动态链接器环境变量的更多信息。
这个方法非常通用。 但也有限制:
dlsym()
加载malloc
的地址来欺骗您,则调用不会被转移。 然而,除非你也通过转移dlsym
来欺骗它!I would use library preloading for this task, because it does not require modification of the running program. If you're familiar with the usual Unix way to do this, it's almost a matter of replacing LD_PRELOAD with DYLD_INSERT_LIBRARIES.
First step is to create a library with code such as this, then build it using regular shared library linking options (
gcc -dynamiclib
):Note that if you also divert
calloc()
and its implementation callsmalloc()
, you may need additional code to check how you're being called. C++ programs should be pretty safe because thenew
operator callsmalloc()
anyway, but be aware that no standard enforces that. I have never encountered an implementation that didn't usemalloc()
, though.Finally, set up the running environment for your program and launch it (might require adjustments depending on how your shell handles environment variables):
See the dyld manual page for more information about the dynamic linker environment variables.
This method is pretty generic. There are limitations, however:
dlsym()
to loadmalloc
's address, the call won't be diverted. Unless, however, you trick it back by also divertingdlsym
!http: 中提到的
malloc_default_zone
技术: //lists.apple.com/archives/darwin-dev/2005/Apr/msg00050.html 似乎仍然有效,请参见 http://code.google.com/p/fileview/source/browse/trunk/fileview/ fv_zone.cpp?spec=svn354&r=354 的示例使用似乎与您的意图类似。The
malloc_default_zone
technique mentioned at http://lists.apple.com/archives/darwin-dev/2005/Apr/msg00050.html appears to still work, see e.g. http://code.google.com/p/fileview/source/browse/trunk/fileview/fv_zone.cpp?spec=svn354&r=354 for an example use that seems to be similar to what you intend.经过大量搜索(包括此处)和 10.7 的问题后,我决定写一篇关于此主题的博客文章:如何在 OSX Lion 中设置 malloc 挂钩
您会在文章末尾找到一些很好的链接,其中包含有关此主题的更多信息。
基本解决方案:
After much searching (here included) and issues with 10.7 I decided to write a blog post about this topic: How to set malloc hooks in OSX Lion
You'll find a few good links at the end of the post with more information on this topic.
The basic solution:
这是一个老问题,但我在尝试自己做这件事时遇到了它。 我对我正在从事的个人项目的这个主题感到好奇,主要是为了确保我认为自动释放的内容被正确释放。 我最终编写了一个 C++ 实现,以允许我跟踪分配的堆的数量,并在我选择的情况下将其报告出来。
https://gist.github.com/monitorjbl/3dc6d62cf5514892d5ab22a59ff34861
顾名思义,这是 OSX -具体的。 但是,我可以使用
malloc_usable_size
示例
构建
在 Linux 环境中执行此操作,希望这对其他人将来有所帮助!
This is an old question, but I came across it while trying to do this myself. I got curious about this topic for a personal project I was working on, mainly to make sure that what I thought was automatically deallocated was being properly deallocated. I ended up writing a C++ implementation to allow me to track the amount of allocated heap and report it out if I so chose.
https://gist.github.com/monitorjbl/3dc6d62cf5514892d5ab22a59ff34861
As the name notes, this is OSX-specific. However, I was able to do this on Linux environments using the
malloc_usable_size
Example
Building
Hope this helps someone else out in the future!
如果您需要的基本统计信息可以在一个简单的包装器中收集,那么一个快速(而且有点肮脏)的技巧就是使用一些
#define
宏替换。和
注意:如果宏是在 _mymalloc 定义之前定义的,它将最终替换该函数内的 malloc 调用,从而使您陷入无限递归......所以请确保这不是'情况如此。 您可能希望在该函数定义之前显式地
#undef
它,然后根据最终包含它的位置简单地(重新)定义它,以期避免这种情况。If the basic stats you need can be collected in a simple wrapper, a quick (and kinda dirty) trick is just using some
#define
macro replacement.and
Note: if the macro is defined before the _mymalloc definition it will end up replacing the malloc call inside that function leaving you with infinite recursion... so ensure this isn't the case. You might want to explicitly
#undef
it before that function definition and simply (re)define it afterward depending on where you end up including it to hopefully avoid this situation.我认为如果您在项目中包含的您自己的 .c 文件中定义了 malloc() 和 free() ,则链接器将解析该版本。
那么,你打算如何实现malloc呢?
I think if you define a malloc() and free() in your own .c file included in the project the linker will resolve that version.
Now then, how do you intend to implement malloc?
查看 Emery Berger(Hoard 内存分配器的作者)在 OSX 上替换分配器的方法,网址为 https://github.com/emeryberger/Heap-Layers/blob/master/wrappers/macwrapper.cpp (以及一些其他文件,您可以通过以下包含内容来跟踪自己) 。
这是对 Alex 答案的补充,但我认为这个例子更能说明替换系统提供的分配器的问题。
Check out Emery Berger's -- the author of the Hoard memory allocator's -- approach for replacing the allocator on OSX at https://github.com/emeryberger/Heap-Layers/blob/master/wrappers/macwrapper.cpp (and a few other files you can trace yourself by following the includes).
This is complementary to Alex's answer, but I thought this example was more to-the-point of replacing the system provided allocator.