C/C++动态链接库重载

4
在我的项目中,我需要修改glibc源代码的一些函数。我只需要修改部分pthread。例如,我在源代码中修改了多线程相关的函数,如pthread_create.c或pthread_mutex_lock.c。然后,当我的具体程序运行时,我想指定它在需要使用这些函数时使用修改后的函数,并且不会影响其他函数。另外,我不想在程序运行时指定整个版本的glibc。请问有没有好的解决方案?谢谢!Ding

6
为什么不直接使用另一个名称,而要替换标准函数? - Aganju
你的意思是想替换某些glibc函数的所有实例,并保留其他函数的实现吗?如果是这样,你可以尝试使用LD_PRELOAD来加载包含替换函数的SO中的符号。 - Robert Prévost
谢谢你的帮助。实际上,我需要在pthread函数内获取一个特定的参数,比如系统分配的线程ID。因此,我在函数内插入了一个例程,并重新编译了修改后的glibc,然后使用一个工具来对我的例程进行插桩以获取该参数。正如你建议的那样,我想重写pthread函数,但是在glibc源代码中存在复杂的关系调用,所以我尝试重新编译整个glibc并预加载libpthread.so。但是,如果系统glibc版本与我的版本不同,则无法工作。我感到困惑。 - SJ.Ding
1个回答

1
这是一个共享库拦截器的工作。这里有一篇很好的文章。
如果一个函数在共享库中,运行时链接器可以被指示调用另一个“拦截”函数。拦截器可以完全替换功能或增强功能。一个很好的例子是malloc函数族,一个内存泄漏检测器和堆报告工具可以基于用户程序和系统调用之间的一组拦截器。
拦截器仅适用于共享(.so)库。静态(.a)库直接链接到可执行文件中,调用不能轻易地被拦截。
所有主要的Linux版本都支持LD_PRELOAD功能的拦截器。 这里是一个pthread_create的示例拦截器。

感谢您的帮助。实际上,我需要在pthread函数内获取特定参数,例如系统分配的线程ID。因此,我在函数内插入了一个例程,并重新编译了修改后的glibc,然后使用了一个工具来检测我的例程以获取该参数。正如您建议的那样,我想重写pthread函数,但是在glibc源代码中存在复杂的关系调用,因此我无法进行操作。因此,我尝试重新编译整个glibc,并仅预加载libpthread.so。但是,如果系统glibc版本与我的版本不同,则无法正常工作。我很困惑。 - SJ.Ding
保留glibc不变。将pthread_create的实现复制到您的interposer中。在interposer版本中,添加您的自定义代码。如果您的函数具有不同的签名,只需创建一个新函数,例如my_pthread_create,并像往常一样链接而无需使用interposer。 - Matthew Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接