在运行时用LD_PRELOAD链接函数
Linking functions with LD_PRELOAD at runtime
我正在编写一个库,通过运行LD_PRELOAD=mylib myexe
程序来拦截对malloc
和free
的调用。
对malloc
和free
的呼叫均截取良好。我的问题是,在mylib中还有另一个函数,当使用LD_PRELOAD
时,我也想要拦截,我无法弄清楚为什么它不像调用malloc
和free
一样"只工作"。
void* malloc(size_t s)
{
return doMyMalloc();
}
void free(void* p)
{
doMyFree(p);
}
void otherThing(size_t)
{
doThing();
}
在myexe.cpp: #include <malloc.h>
extern "C" void otherThing(size_t); // Compile with -Wl,--unresolved-symbols=ignore-all
int main(int argc, char* argv[])
{
void* x = malloc(1000); // Successfully intercepted.
free(x); // Successfully intercepted.
otherThing(1); // Segfault.
}
我设法使它工作的一种方法是:
typedef void (*FUNC)(size_t);
FUNC otherThing = NULL;
int main(int argc, char* argv[])
{
otherThing = (FUNC)dlsym(RTLD_NEXT, "otherThing");
otherThing(1); // Successfully calls mylib's otherThing().
}
但是我不想写这些代码;我不需要为malloc
和free
做这些。如果缺少LD_PRELOAD
前缀,程序崩溃也没关系。
我觉得你是在用一个解决方案(LD_PRELOAD
)来解决两个不同的问题。首先,要对malloc()
和free()
打补丁。你成功了,太棒了。接下来,您希望拥有一个运行时"插件"系统,在构建时不链接任何库,而只在运行时链接。这通常是使用dlopen()
和dlsym()
完成的,我建议您使用它们。
这个想法是,您不想在构建时指定otherThing()
的特定实现,但您确实需要在运行时有一些实现(或者您正确地期望崩溃)。所以让我们明确一点,在运行时使用dlsym()
来解析函数名,当然,如果找不到它,会进行错误检测。
至于在哪里定义otherThing()
,它可以在一个完全独立的文件给dlopen()
,或在mylib
(在这种情况下传递NULL作为文件名给dlopen()
)。
这个问题有点棘手。网上有很多关于这个的帖子,但我将试着把它分解成"让它工作"。
如果这是在Linux下,那么发生的事情是应用程序已被编译为无法使用外部符号。最快的解决方案是在主应用程序中添加与库中使用的相同的编译标志,即在主应用程序的编译中添加-fPIC
标志,就像对库所做的那样。
与其使用-Wl,--unresolved-symbols=ignore-all
标志,不如使用__attribute__ ((weak))
,如:
extern "C" void otherThing(size_t) __attribute__ ((weak);
并在运行时检查它是否为NULL,这将允许您确定它是否已设置。
通过以与.so
相同的方式编译主应用程序,您隐式地允许将其本身用作LD_PRELOAD
的目标,如手册页:
LD_PRELOAD
附加的用户指定的ELF共享库列表在其他所有人之前装载。列表中的项可以用。分隔空格或冒号。这可以用来选择性地覆盖.
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- CMake-按正确顺序将项目与C运行时对象文件链接
- 从链接列表c++中删除一个项目
- 有根的二进制搜索树.保留与其父级的链接
- 读取文件的最后一行并输入到链接列表时出错
- 静态数据成员的问题-修复链接错误会导致编译器错误
- node-gyp 在 macOS 上未正确链接库
- 基于boost的程序的静态链接——zlib问题
- 无法链接 CMake 中的本地库
- 内联函数中具有内部链接的全局变量
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 使用gcc从静态链接的文件中查找可选符号
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 下面是我为检测链接列表中的循环而制作的代码
- 有了gcc,是否可以链接库,但前提是它存在
- 使用C链接在函数内部创建C++模板
- Visual Studio mkl_link_tool.exe链接错误
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- 有人能帮我处理这个链接列表吗?C++