我想维护所有正在运行的线程的列表,其中包含有关每个线程的一些其他信息。在这提到的answer中,可以提供我自己的pthread_create版本并将程序与它链接。 同样重要的是,我想在我的覆盖版本的末尾调用原始的pthread_create。
有人可以详细解释如何完成和/或提供一些代码示例吗?
答案 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库的正确名称。