关于共享库和线程特定数据的问题

时间:2011-09-18 07:54:09

标签: c linux pthreads shared-libraries

这个问题是关于gdb and valgrind within a makefile的。我发现了前一个问题中指出的分段错误的原因,我现在不知道如何解决这个问题。对不起,我无法发布代码,因为它分散在多个文件中,因此往往非常庞大。

查看Makefile

all: clients.so simulator backup     
    LD_PRELOAD=/home/Juggler/client/clients.so ./simulator 
backup: backup.c libclient.a  
    gcc backup.c -o backup -L /home/Juggler/client -L. -lclient -ldl 
simulator: simulator.c libclient.a
    gcc -g simulator.c -o simulator -L /home/Juggler/client -L. -lclient -ldl -pthread 

libclient.a: libclient.o client.o  
    ar rcs libclient.a libclient.o client.o
libclient.o:libclient.c
   gcc -c libclient.c -o libclient.o -pthread
clients.so: client.o client_invoke.o
   ld -shared -o clients.so client_invoke.o client.o -ldl
client_invoke.o: client_invoke.c
   gcc -Wall -fPIC -DPIC -c -g client_invoke.c
client.o: client.c
   gcc -Wall -fPIC -DPIC -c -g client.c -ldl -pthread

模拟器启动许多线程,每个线程首先使用libclient.a中的函数来访问client.c,其中通过套接字连接到服务器。每个线程通过不同的套接字连接到服务器,并使用pthread_keycreate及其函数系列来保持套接字值线程特定。来自每个线程的其他调用(打开,读取等)通过共享库client.so进行预加载,然后到client.c,通过特定于线程的套接字向服务器发送消息。

现在,问题是从一个线程通过libclient.a获取服务器的任何消息使用特定于线程的套接字但是任何通过客户端获取路由的消息。所以共享库在send()上遇到分段错误。我尝试打印出套接字描述符,它在第一个路径中打印但不在第二个路径中打印...在print语句中发生了段错误。

特定于线程的数据和共享库是否有效?

由于

编辑:段错误中的代码

int call_execute(char *argcalls[])
{
  int *saved_socket;
  saved_socket = (int*)pthread_getspecific(key_to_sockfd);
   .....
  n = send(*saved_sockfd,argcalls[i],strlen(argcalls[i]),0);//segfault here.argcalls[i] not giving segfault

  ...

}

很乐意澄清。发生segfault时,从client_invoke调用call_execute。但是当从libclient.c调用它时,它可以正常工作。

1 个答案:

答案 0 :(得分:1)

是的,TSS和共享库原则上工作,但有一点需要注意:根据我在mingw-cross-compiling中遇到类似问题的经验,我假设您的pthread库也必须动态链接以为线程提供公共存储位置特定数据。我认为gcc通常不会这样,但我不确定。两个建议:

  1. 尝试使用-shared-libgcc进行链接。
  2. 将分配套接字的代码重新定位到第三个库中和/或将其保存在client.so中,仅传播指向结构的指针。