gpt4 book ai didi

sockets - LD_PRELOAD 使用 gcc 或 g++ 编译 .so

转载 作者:行者123 更新时间:2023-12-03 11:53:57 24 4
gpt4 key购买 nike

我有一个套接字 API 的包装器,我在我的应用程序使用 LD_PRELOAD 之前预加载它。但是,当我使用 g++ 编译我的 .so 包装器库时,它不起作用,即,套接字实现的 glibc 版本是 picketd 。

这就是我编译包装器 .so 库(其中之一)的方式:

gcc -Wall -fPIC -shared socket_hooks.c -o socket_hooks.so
or
g++ -Wall -fPIC -shared socket_hooks.c -o socket_hooks.so

这就是我编译和运行我的 udp 客户端的方式:
g++ -Wall udp_client.cpp  -o udp_client
LD_PRELOAD=./socket_hooks.so ./udp_client

现在,当我启用调试(导出 LD_DEBUG=all)并使用使用 编译的 .so 运行时海合会 (工作版)我看到的编译示例:
 17278: symbol=socket;  lookup in file=./udp_client [0]
17278: symbol=socket; lookup in file=./socket_hooks.so [0]
17278: binding file ./udp_client [0] to ./socket_hooks.so [0]: normal symbol `socket' [GLIBC_2.2.5]

当我使用 编译 .so 时g++ 我看到以下内容:
 17285: symbol=socket;  lookup in file=./udp_client [0]
17285: symbol=socket; lookup in file=./socket_hooks.so [0]
17285: symbol=socket; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
17285: binding file ./udp_client [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `socket' [GLIBC_2.2.5]

在这两种情况下都找到了“socket”符号,但在后一种情况下它没有被拾取,而是使用 libc。

你能解释一下这里发生了什么吗?

最佳答案

当你用 C++ 编译器编译你的模块时,你的符号名称会被修改以支持函数重载,例如 socket可以转换为 _Z10socketiii .这就是运行时加载程序找不到它的原因 - 它正在寻找 socket ,而不是 _Z10socketiii .

为了禁用名称修改,您必须使用 extern "C" 使用 C 链接声明您的函数,可能与 __cplusplus 结合使用宏,为了与 C 编译器保持兼容:

#ifdef __cplusplus
extern "C" {
#endif

int socket(int domain, int type, int protocol);

#ifdef __cplusplus
}
#endif

或者,基于每个符号设置链接:
#ifdef __cplusplus
#define DONT_MANGLE_ME extern "C"
#else
#define DONT_MANGLE_ME
#endif

DONT_MANGLE_ME int socket(int domain, int type, int protocol);

关于sockets - LD_PRELOAD 使用 gcc 或 g++ 编译 .so,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37875405/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com