如何在OS X下覆盖malloc(),calloc(),free()等?

11 malloc macos xcode overriding

假设最新的XCode和GCC,覆盖内存分配函数的正确方法是什么(我猜运算符new/delete也是如此).调试内存分配器对于游戏来说太慢了,我只需要一些基本的统计数据,我可以自己做,影响最小.

我知道它在Linux中很容易因为钩子而存在,而且在十年前编写HeapManager时,这在codewarrior下是微不足道的.

可悲的是,smartheap不再有mac版本.

sam*_*var 9

我会使用库预加载来完成此任务,因为它不需要修改正在运行的程序.如果您熟悉通常的Unix方法,那么几乎就是用DYLD_INSERT_LIBRARIES替换LD_PRELOAD.

第一步是创建一个包含此类代码的库,然后使用常规共享库链接选项(gcc -dynamiclib)构建它:

void *malloc(size_t size)
{
    void * (*real_malloc)(size_t);
    real_malloc = dlsym(RTLD_NEXT, "malloc");

    fprintf(stderr, "allocating %lu bytes\n", (unsigned long)size);
    /* Do your stuff here */

    return real_malloc(size);
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您也转移calloc()及其实现调用malloc(),则可能需要其他代码来检查您的调用方式.C++程序应该非常安全,因为new操作员malloc()无论如何都要调用,但要注意没有标准强制执行.但是,我从未遇到过没有使用的实现malloc().

最后,为程序设置运行环境并启动它(可能需要根据shell处理环境变量的方式进行调整):

export DYLD_INSERT_LIBRARIES=./yourlibrary.dylib
export DYLD_FORCE_FLAT_NAMESPACE=1
yourprogram --yourargs
Run Code Online (Sandbox Code Playgroud)

有关动态链接器环境变量的更多信息,请参见dyld手册页.

这种方法非常通用.但是有一些限制:

  • 您将无法转移直接系统呼叫
  • 如果应用程序本身通过使用dlsym()加载malloc的地址欺骗您,则不会转移呼叫.但是,除非你通过转移来欺骗它dlsym!


Ale*_*lli 3

http://lists.apple.com/archives/darwin-dev/2005/Apr/msg00050.htmlmalloc_default_zone中提到的技术似乎仍然有效,请参阅http://code.google.com/p/fileview/source/ browser/trunk/fileview/fv_zone.cpp?spec=svn354&r=354 的示例使用似乎与您的意图类似。

  • 这是一个很好的例子,但我认为完全替换 OSX 内存分配器的更清晰的例子可以在 https://github.com/emeryberger/Heap-Layers/blob/master/wrappers/macwrapper.cpp 上找到。不过……原来的电子邮件线程很棒。:) (2认同)