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

2023-12-25

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

由于钩子,我知道它在 Linux 中很容易,十年前当我编写 HeapManager 时,这在 codewarrior 下是微不足道的。

遗憾的是 smartheap 不再有 mac 版本。


我将使用库预加载来完成此任务,因为它不需要修改正在运行的程序。如果您熟悉执行此操作的常用 Unix 方法,那么几乎只需将 LD_PRELOAD 替换为 DYLD_INSERT_LIBRARIES 即可。

第一步是使用此类代码创建一个库,然后使用常规共享库链接选项构建它(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);
}

请注意,如果您还转移calloc()及其实现调用malloc(),您可能需要额外的代码来检查您的呼叫方式。 C++ 程序应该非常安全,因为new接线员呼叫malloc()无论如何,但请注意,没有标准强制执行这一点。我从未遇到过不使用的实现malloc(), 尽管。

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

export DYLD_INSERT_LIBRARIES=./yourlibrary.dylib
export DYLD_FORCE_FLAT_NAMESPACE=1
yourprogram --yourargs

See dyld 手册页 http://developer.apple.com/documentation/Darwin/Reference/Manpages/man1/dyld.1.html有关动态链接器环境变量的更多信息。

这个方法非常通用。但也有一些限制:

  • 您将无法转移直接系统调用
  • 如果应用程序本身通过使用来欺骗您dlsym()加载malloc的地址,呼叫不会被转移。然而,除非你也通过转移来欺骗它dlsym!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我如何在 OS X 下覆盖 malloc()、calloc()、free() 等? 的相关文章

随机推荐