我有一些应用程序需要使用共享库来编写扩展。在我的共享库中,我需要使用线程。主应用程序既不使用与线程库(例如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