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

发布于 2024-12-04 22:04:51 字数 1750 浏览 0 评论 0原文

这个问题参考makefile 中的 gdb 和 valgrind。我发现了上一个问题中指出的分段错误的原因,但我现在不知道如何解决该问题。很抱歉,我无法发布代码,因为它分布在多个文件中,因此往往非常庞大。

查看 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

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

现在,问题是从采用 libclient.a 路由的线程发送到服务器的任何消息都使用线程特定的套接字,但通过 client.so 共享库采用路由的任何消息都会在 send() 上遇到分段错误。我尝试打印出套接字描述符,它在第一个路由中打印,但在第二个路由中不打印...打印语句中出现段错误。

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

谢谢

编辑:段错误及其周围的代码

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

  ...

}

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

This question is in reference to gdb and valgrind within a makefile. I found the reason of segmentation fault as pointed out in the previous quetion and I now don't know how to solve the issue. I am sorry i shall not be able to post the code as it spreads across multiple files and hence tends to be quite huge.

looking at the 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

Simulator starts a number of threads and each thread first uses functions in libclient.a to reach client.c where connection is made to a server thru sockets. Each thread is connected to the server via a different socket and have used the pthread_keycreate and its family of functions to keep the socket value thread specific. Other calls from each thread(open,read etc) goes through the shared library client.so that was preloaded and then to client.c to send message to server through the thread specific socket.

Now, the problem is any message to server from a thread that takes the route through libclient.a uses the thread-specific socket but any message that takes the route through clients.so shared library encounters a segmentation fault on send(). I tried printing out the socket descriptor and it prints in the first route but not the second...segfault occurs in the print statement.

Does thread-specific data and shared library work?

Thanks

Edit: Code in and around segfault

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

  ...

}

Would be happy to clarify. call_execute is called from client_invoke when the segfault occurs. But when it is called from libclient.c it works fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦言归人 2024-12-11 22:04:51

是的,TSS 和共享库原则上可以工作,但有一个警告:根据我在 mingw 交叉编译中遇到类似问题的经验,我假设您的 pthread 库也必须动态链接,以便为线程特定的数据提供一个公共存储位置。我认为海湾合作委员会通常不会出现这种情况,但我不确定这一点。两个建议:

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

Yes, TSS and shared libraries work in principle, with one caveat: From my experience with similar issues in mingw-cross-compiling, I assume that your pthread library must also be linked dynamically to provide a common storage location for the thread-specific data. I don't think this is the case normally for gcc, but am not sure about that. Two suggestions:

  1. Try linking with -shared-libgcc.
  2. Relocate the code that allocates the socket into a third library and/or keep it purely in client.so, propagating only the pointer to the struct.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文