调试_libc_start_main中的函数

调试_libc_start_main中的函数,c,linux,debugging,gdb,C,Linux,Debugging,Gdb,我正在编写一个库,它钩住一些CUDA函数来添加一些功能。构造函数钩住CUDA函数,并设置消息队列和共享内存,以便与其他钩住的CUDA二进制文件通信。当python subprocess.Popen启动几个钩住的CUDA二进制文件时,shell=True一些进程挂起。所以我用gdb-p附加了一个挂起的进程,希望找出哪里出了问题。结果如下: Attaching to process 7445 Reading symbols from /bin/dash...(no debugging symbols

我正在编写一个库,它钩住一些CUDA函数来添加一些功能。构造函数钩住CUDA函数,并设置消息队列和共享内存,以便与其他钩住的CUDA二进制文件通信。当python subprocess.Popen启动几个钩住的CUDA二进制文件时,shell=True一些进程挂起。所以我用gdb-p附加了一个挂起的进程,希望找出哪里出了问题。结果如下:

Attaching to process 7445
Reading symbols from /bin/dash...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.27.so...done.
done.
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.27.so...done.
done.
0x00007f9cefe8b76a in wait4 () at ../sysdeps/unix/syscall-template.S:78
78      ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) bt
#0  0x00007f9cefe8b76a in wait4 () at ../sysdeps/unix/syscall-template.S:78
#1  0x000055fff93be8a0 in ?? ()
#2  0x000055fff93c009d in ?? ()
#3  0x000055fff93ba6d8 in ?? ()
#4  0x000055fff93b949e in ?? ()
#5  0x000055fff93b9eda in ?? ()
#6  0x000055fff93b7944 in ?? ()
#7  0x00007f9cefdc8b97 in __libc_start_main (main=0x55fff93b7850, argc=3, argv=0x7ffca7c7beb8, init=<optimized out>,
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffca7c7bea8) at ../csu/libc-start.c:310
#8  0x000055fff93b7a4a in ?? ()
我添加了-g标志,但程序似乎在进入main之前挂起了wait4

感谢您对以下方面的见解:

如何加载这些调试符号以消除?? ../csu/libc start.c:310在哪里? 我还可以做些什么来定位bug? 系统信息:gcc 6.5.0,Ubuntu 18.04和4.15.0-54-generic

如何加载这些调试符号以消除

您似乎需要/bin/dash的调试符号,这些符号可能位于名为dash-dbg或dash-dbgsym之类的包中

此外,如果使用-fno优化同级调用编译库,我怀疑堆栈跟踪会更有意义

../csu/libc start.c:310在哪里

我还可以做些什么来定位bug

您说您正在编写一个使用_属性_构造函数的库,但您显示了/bin/dash的堆栈跟踪,我认为它不是您编写的一个程序,它似乎不涉及库中的符号。我由此推断,您的库已加载LD_PRELOAD到不希望它出现的程序中

这两件事——LD_PRELOAD和_attribute__constructor——都打破了对涉及到的任何毫无戒心的程序和C库的正常期望。只有在没有其他选择的情况下,才应该执行这些操作,并且应该在注入的代码中尽可能少地执行这些操作。特别是,我认为任何涉及从构造函数派生进程的设计都是不可行的,当然。如果你告诉我们你更大的目标,我们可能会建议其他方法,不那么麻烦

编辑:


当shell=True时,Python不会直接调用程序,而是运行/bin/sh-c格式的命令“string passed to Popen”。在许多情况下,这自然会产生一个/bin/dash进程,该进程在实际二进制文件的整个生命周期内不会挂起在等待系统调用中。除非您确实需要在运行程序之前评估一些shell代码,否则请尝试使用默认的shell=False,看看这是否会解决您的问题。如果您确实需要计算shell代码,请尝试Popen';exec',shell=True。

您的库在做什么?为什么它需要使用_属性_构造函数?那个构造函数代码在做什么?提供一个展现麻烦行为的构造函数的实例将使我们更有可能提供一个有用的答案。此外,它还有助于更清楚地描述启动多进程时的场景。@Someprogrammerdude库正在连接一些CUDA函数以添加一些功能。构造函数钩住函数并设置消息队列和共享内存,以便与其他钩住的CUDA二进制文件进行通信。@zingdle我们需要您更加具体。@JohnBollinger我试图将其缩小到一个最小的可复制示例,但这可能需要更多的时间。我钩住了几个CUDA二进制文件并同时启动了它们。谢谢,我现在还没有访问代码的权限,但我会尽快尝试你的建议。我正在将日志重定向到文件。如何使用shell=False实现这一点?例如,您可以将subprocess.Popen'binary>log.txt',shell=True替换为subprocess.Popen['binary',shell=False,stdout=openlog.txt,w。我建议通读Popen关键字参数的完整列表。现在我可以通过设置shell=False来附加到进程。结果是,其中一个进程耗尽了资源,然后崩溃,其他进程正在等待同步。
subprocess.Popen('<path-to-binary>', shell=True)