如何在链接期间替换pthread_create

时间:2016-01-17 16:15:14

标签: c linux multithreading posix

我想维护所有正在运行的线程的列表,其中包含有关每个线程的一些其他信息。在这提到的answer中,可以提供我自己的pthread_create版本并将程序与它链接。 同样重要的是,我想在我的覆盖版本的末尾调用原始的pthread_create。

有人可以详细解释如何完成和/或提供一些代码示例吗?

2 个答案:

答案 0 :(得分:4)

您可以通过调用:

来查找原始pthread_create函数的符号
pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");

然后包装器看起来像:

#include <dlfcn.h>

int (*pthread_create_orig)(pthread_t *, const pthread_attr_t *, void *(*) (void *), void *);

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start) (void *), void *arg) {
       if (!pthread_create_orig)
           pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");
       return pthread_create_orig(thread, attr, start, arg);
}

将其编译为共享库,并在启动可执行文件时预加载它。

说明:通常,dlsym()的第一个参数是使用dlopen()打开的库的句柄。特殊句柄RTLD_NEXT用于搜索该符号的下一个匹配项,即默认情况下不链接的符号。这是libpthread中的符号,而不是预加载库中的符号。

答案 1 :(得分:3)

如果你真的想要替换这个函数你可以用pthread_create函数编译你自己的共享库,你可以从内部动态加载并调用原来的phtread_create函数。

图书馆代码frm.RefreshFromSettings()

pthread.c

汇编: #include <dlfcn.h> #include <stdio.h> #include <pthread.h> int (*original_pthread_create)(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) = NULL; void load_original_pthread_create() { void *handle = dlopen("libpthread-2.15.so", RTLD_LAZY); char *err = dlerror(); if (err) { printf("%s\n", err); } original_pthread_create = dlsym(handle, "pthread_create"); err = dlerror(); if (err) { printf("%s\n", err); } } int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { if (original_pthread_create == NULL) { load_original_pthread_create(); } printf("I am creating thread from my pthread_create\n"); return original_pthread_create(thread, attr, start_routine, arg); }

使用方法: gcc pthread.c -o libmypthread.so -shared -fpic -ldl

some_program_using_pthread_create应该照常工作,但是每次调用pthread_create函数时都应该打印额外的行。

注意:在dlopen函数中放置pthread库的正确名称。