问题
I want to maintain a list of all running threads with some additional information about each thread. In this answer mentioned that it is possible to provide my own version of pthread_create and to link program with it. It is also important that I want to call original pthread_create in the end of my override version of it.
Could someone explain in details how it could be done and/or provide some code example?
回答1:
You can lookup the symbol for the original pthread_create-function by calling:
pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");
The wrapper would then look like:
#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);
}
Compile this as a shared library and preload it when starting your executable.
Explanation: Usually, the first argument of dlsym()
is a handle to a library opened with dlopen()
. The special handle RTLD_NEXT
is used to search the next occurrence of that symbol, i.e. the one which would not be linked by default. This is then the symbol in libpthread, not the one in your preloaded library.
回答2:
If you really want to replace the function you can compile your own shared library with pthread_create function, from within you can dynamically load and call original phtread_create function.
Library code 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);
}
Compilation:
gcc pthread.c -o libmypthread.so -shared -fpic -ldl
Usage:
LD_PRELOAD=./libmypthread.so some_program_using_pthread_create
some_program_using_pthread_create should work as usual, but with each pthread_create function call it should print additional line.
Note: place correct name of your pthread library in dlopen function.
来源:https://stackoverflow.com/questions/34840510/how-to-replace-pthread-create-during-linkage