2016-01-17 16 views
4

我想維護一個包含每個線程的一些附加信息的所有正在運行的線程的列表。在此answer中提到可以提供我自己的pthread_create版本並將程序與它聯繫起來。 我想在我的覆蓋版本的末尾調用原始pthread_create也很重要。如何在連接期間替換pthread_create

有人可以詳細解釋如何完成和/或提供一些代碼示例?

+1

爲什麼你需要重新定義'pthread_create()'?如果你願意的話,它需要一個參數來精確地傳遞*附加信息。 –

+0

因此,爲附加信息創建一個結構,在線程函數中或調用'pthread_create'之前/之後初始化它。 –

+0

我想重新定義pthread_create,因爲所有附加信息對我的圖書館用戶應該是「不可見的」。即用戶通過普通的pthread_create創建一個新的線程,但在場景中執行一些額外的工作。當然,爲線程提供我自己的API是很簡單的(現在它是如何工作的),但是用戶應該修改它們的源代碼並用我的api替換每個pthread_ *函數。這是我儘量避免的。 – eucpp

回答

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中的符號,而不是預裝庫中的符號。

3

如果您真的想替換函數,您可以使用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函數調用它應打印附加行。

注意:將您的pthread庫的正確名稱放在dlopen函數中。