我有一些應用程序需要使用共享庫來編寫擴展。在我的共享庫中,我需要使用線程。主應用程序既不使用與線程庫(例如libpthread.so)鏈接的線程。非線程共享庫非線程應用程序
由於第一次測試顯示我的庫導致主應用程序崩潰。如果我使用LD_PRELOAD黑客崩潰消失:
LD_PRELOAD=/path/to/libpthread.so ./app
在那裏我有沒有段錯誤不LD_PRELOAD黑客唯一的操作系統是OS X.在其他它只是崩潰。我測試過:Linux,FreeBSD,NetBSD。
我的問題是:有沒有辦法讓我的線程共享庫安全的非線程應用程序,而不改變主應用程序和LD_PRELOAD黑客?
要重現該問題我寫簡單的例子:
mylib.c
#include <pthread.h>
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *_thread(void *arg) {
int i;
struct addrinfo *res;
for (i=0; i<10000; i++) {
if (getaddrinfo("localhost", NULL, NULL, &res) == 0) {
if (res) freeaddrinfo(res);
}
}
pthread_mutex_lock(&mutex);
printf("Just another thread message!\n");
pthread_mutex_unlock(&mutex);
return NULL;
}
void make_thread() {
pthread_t tid[10];
int i, rc;
for (i=0; i<10; i++) {
rc = pthread_create(&tid[i], NULL, _thread, NULL);
assert(rc == 0);
}
void *rv;
for (i=0; i<10; i++) {
rc = pthread_join(tid[i], &rv);
assert(rc == 0);
}
}
的main.c
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *mylib_hdl;
void (*make_thread)();
mylib_hdl = dlopen("./libmy.so", RTLD_NOW);
if (mylib_hdl == NULL) {
printf("dlopen: %s\n", dlerror());
return 1;
}
make_thread = (void (*)()) dlsym(mylib_hdl, "make_thread");
if (make_thread == NULL) {
printf("dlsym: %s\n", dlerror());
return 1;
}
(*make_thread)();
return 0;
}
的Makefile
all:
cc -pthread -fPIC -c mylib.c
cc -pthread -shared -o libmy.so mylib.o
cc -o main main.c -ldl
clean:
rm *.o *.so main
$ make
cc -pthread -fPIC -c mylib.c
cc -pthread -shared -o libmy.so mylib.o
cc -o main main.c -ldl
$ ./main
*** glibc detected *** ./main: double free or corruption (fasttop): 0x0000000001614c40 ***
Segmentation fault
$ ldd libmy.so | grep thr
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe7e2591000)
$ LD_PRELOAD=/lib/x86_64-linux-gnu/libpthread.so.0 ./main
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
Just another thread message!
-1,答案根本就是錯的。 – 2014-10-04 11:58:39
@JensGustedt:'-pthread'不是'-lpthread',即它是「特殊的」。它取決於實現,但用'-pthread'編譯你的程序可能會添加預處理器定義,這會改變標準庫的行爲。也許我應該改變我的答案,即使LD_PRELOAD技巧使得程序無效,儘管它顯然適用於某些人。但是它可能不是可移植的(即使在通常支持LD_PRELOAD的系統中也是如此)。 – 2014-10-04 12:43:34