联动时如何替换pthread_create
How to replace pthread_create during linkage
我想维护一个包含所有 运行 个线程的列表,其中包含有关每个线程的一些附加信息。在此 answer 中提到可以提供我自己的 pthread_create 版本并用它编写 link 程序。
同样重要的是,我想在覆盖版本的末尾调用 original pthread_create 。
有人可以详细解释一下如何完成吗and/or提供一些代码示例吗?
如果你真的想替换函数,你可以用 pthread_create 函数编译你自己的共享库,从中你可以动态加载和调用原始 phtread_create 函数。
图书馆代码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
用法:
LD_PRELOAD=./libmypthread.so some_program_using_pthread_create
some_program_using_pthread_create 应该像往常一样工作,但是每个 pthread_create 函数调用它应该打印额外的行。
注意:在 dlopen 函数中放置正确的 pthread 库名称。
您可以通过调用查找原始 pthread_create-function 的符号:
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 中的符号,而不是预加载库中的符号。
我想维护一个包含所有 运行 个线程的列表,其中包含有关每个线程的一些附加信息。在此 answer 中提到可以提供我自己的 pthread_create 版本并用它编写 link 程序。 同样重要的是,我想在覆盖版本的末尾调用 original pthread_create 。
有人可以详细解释一下如何完成吗and/or提供一些代码示例吗?
如果你真的想替换函数,你可以用 pthread_create 函数编译你自己的共享库,从中你可以动态加载和调用原始 phtread_create 函数。
图书馆代码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
用法:
LD_PRELOAD=./libmypthread.so some_program_using_pthread_create
some_program_using_pthread_create 应该像往常一样工作,但是每个 pthread_create 函数调用它应该打印额外的行。
注意:在 dlopen 函数中放置正确的 pthread 库名称。
您可以通过调用查找原始 pthread_create-function 的符号:
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 中的符号,而不是预加载库中的符号。