我正在嘗試使用LD_PRELOAD機制來調用pthread_cond_broadcast。我插入的pthread_cond_broadcast函數只是調用原始的pthread_cond_broadcast。然而,對於pthread_cond_wait和pthread_cond_broadcast都被調用的非常簡單的pthread代碼,我最終會在glibc中得到一個段錯誤(對於glibc 2.11.1)或程序掛起(對於glibc 2.15)。任何線索都在發生?pthread_cond_broadcast破解與dlsym?
的插入代碼(即獲取編譯作爲共享庫):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <dlfcn.h>
static int (*orig_pthread_cond_broadcast)(pthread_cond_t *cond) = NULL;
__attribute__((constructor))
static void start() {
orig_pthread_cond_broadcast =
(int (*)()) dlsym(RTLD_NEXT, "pthread_cond_broadcast");
if (orig_pthread_cond_broadcast == NULL) {
printf("pthread_cond_broadcast not found!!!\n");
exit(1);
}
}
__attribute__((__visibility__("default")))
int pthread_cond_broadcast(pthread_cond_t *cond) {
return orig_pthread_cond_broadcast(cond);
}
簡單並行線程程序:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t cond_mutex;
pthread_cond_t cond_var;
int condition;
void *thread0_work(void *arg) {
pthread_mutex_lock(&cond_mutex);
printf("Signal\n");
condition = 1;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&cond_mutex);
return NULL;
}
void *thread1_work(void *arg) {
pthread_mutex_lock(&cond_mutex);
while (condition == 0) {
printf("Wait\n");
pthread_cond_wait(&cond_var, &cond_mutex);
printf("Done waiting\n");
}
pthread_mutex_unlock(&cond_mutex);
return NULL;
}
int main() {
pthread_t thread1;
pthread_mutex_init(&cond_mutex, NULL);
pthread_cond_init(&cond_var, NULL);
pthread_create(&thread1, NULL, thread1_work, NULL);
// Slowdown this thread, so the thread 1 does pthread_cond_wait.
usleep(1000);
thread0_work(NULL);
pthread_join(thread1, NULL);
return 0;
}
編輯:
的Glibc 2.11.1,GDB BT給出:
(gdb) set environment LD_PRELOAD=./libintercept.so
(gdb) run
Starting program: /home/seguljac/intercept/main
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff7436700 (LWP 19165)]
Wait
Signal
Before pthread_cond_broadcast
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79ca0e7 in [email protected]@GLIBC_2.3.2() from /lib/libpthread.so.0
(gdb) bt
#0 0x00007ffff79ca0e7 in [email protected]@GLIBC_2.3.2() from /lib/libpthread.so.0
#1 0x00007ffff7bdb769 in pthread_cond_broadcast() from ./libintercept.so
#2 0x00000000004008e8 in thread0_work()
#3 0x00000000004009a4 in main()
編輯2:
(已解決) 正如R ..(謝謝!)所建議的,問題是在我的平臺上,pthread_cond_broadcast是一個版本化符號,而dlsym給出了錯誤的版本。此博客解釋這個情況很詳細:http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/
什麼是backtr如果您在調試器下運行王牌的樣子?你有沒有嘗試單步執行代碼? –
我注意到它是一個版本化的符號。 「dlsym」能否給你錯誤的版本? –