阻止调用 `dlsym` (RTLD_NEXT)

blocking call to `dlsym` (RTLD_NEXT)

我正在尝试包装函数。为此,我考虑在注入动态库后使用 dlsym 获取内存中的实际函数位置。

我正在 运行宁 MacOS Mojave (10.14.6)Apple clang version 11.0.0 (clang-1100.0.33.8)

我尝试 运行 一个相当简单的代码,每次调用 malloc 时都会显示一条消息。

所以我使用了这个post的代码:Overriding 'malloc' using the LD_PRELOAD mechanism

我的测试代码是:

#include <stdlib.h>

int main()
{
    (void)malloc(1);
    (void)malloc(1);
    return (0);
}

我在 OSX 上使用 DYLD_INSERT_LIBRARIES=./mylib.so DYLD_FORCE_FLAT_NAMESPACE=1 并在 Ubuntu 上使用 LD_PRELOAD=./mylib.so 注入了动态库。

在 OSX 上,程序阻塞 dlsym 调用,而在 Ubuntu docker 框上,程序运行正常。

编辑:

正如@R.. 所指出的,OSX 上的 dlsym 实现正在调用 malloc(参见来源:https://opensource.apple.com/source/cctools/cctools-667.8.0/libdyld/dlopen.c

很可能调用 dlsym 会导致对 malloc 的递归调用,进而导致对 dlsym 的递归调用,第二次死锁,因为它已经持有一些锁.使用预加载库 wrap malloc,而不是完全替换它,通常不是一个好主意,出于这个和其他原因。

您可以使用 LD_AUDIT 或 OSX 上的等效功能(如果有)来打印调用 malloc 时的踪迹。否则,您可以放入带有调试输出的完整替换 malloc。

你也可能因为调用fprintf()而陷入无限递归,所以使用这段代码插入malloc()是危险的(复制自linked question):

void *malloc(size_t size)
{
    void *p = NULL;
    fprintf(stderr, "malloc(%d) = ", size);
    p = real_malloc(size);
    fprintf(stderr, "%p\n", p);
    return p;
}

fprintf()等库代码很可能会调用malloc().