【发布时间】:2017-08-07 06:07:35
【问题描述】:
我遇到一个或多个线程相互锁定的问题。我不知道那里发生了什么。调试器无法中断(线程 1),中断但无法获取回溯(线程 2+5)或显示回溯(线程 3)
我learned 是这种情况,因为 libc 在汇编程序中实现了这一点,而 gdb 无法正确地 walt 堆栈。有时(我不知道什么时候),我可以在程序集中执行几个步骤,然后我会看到回溯。
我刚刚尝试了一个 x64 程序,它可以工作。
查看我的示例代码:
#include <time.h>
int main()
{
while(1)
{
struct timespec ts;
ts.tv_sec = 1;
ts.tv_nsec = 0;
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, 0);
}
return 1;
}
gdb 输出 32 位:
vagrant@PC41388-spvm-4650:/tmp$ gdb main32
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 版权所有 (C) 2014 Free Software Foundation, Inc. 许可 GPLv3+:GNU GPL 版本 3 或更高版本 http://gnu.org/licenses/gpl.html这是免费软件:你是免费的 改变和重新分配它。没有保证,在某种程度上 法律允许。键入“显示复制”和“显示保修”为 细节。此 GDB 配置为“x86_64-linux-gnu”。输入“显示 配置”以获取配置详细信息。用于错误报告 说明请见:http://www.gnu.org/software/gdb/bugs/。 在线查找 GDB 手册和其他文档资源: http://www.gnu.org/software/gdb/documentation/。如需帮助,请键入 “帮助”。键入“apropos word”以搜索与相关的命令 “word”...从 main32 读取符号...(没有调试符号 找到)...完成。
(gdb) r 启动程序:/tmp/main32 [线程 启用使用 libthread_db 进行调试] 使用主机 libthread_db 库 “/lib/x86_64-linux-gnu/libthread_db.so.1”。 ^C 程序接收到的信号
SIGINT,中断。 0x55579cd9 在?? () (gdb) bt
#0 0x55579cd9 在?? ()
#1 0x555b0af3 in __libc_start_main (main=0x80484dd , argc=1, argv=0xffffcee4,init=0x8048520 <__libc_csu_init>, fini=0x8048590 <__libc_csu_fini>,rtld_fini=0x55564160 <_dl_fini>, stack_end=0xffffcedc) 在 libc-start.c:287
#2 0x08048401 in _start() (gdb)
gdb 输出 64 位:
vagrant@PC41388-spvm-4650:/tmp$ gdb main64
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 版权所有 (C) 2014 Free Software Foundation, Inc. 许可 GPLv3+:GNU GPL 版本 3 或更高版本 http://gnu.org/licenses/gpl.html这是免费软件:你是免费的 改变和重新分配它。没有保证,在某种程度上 法律允许。键入“显示复制”和“显示保修”为 细节。此 GDB 配置为“x86_64-linux-gnu”。输入“显示 配置”以获取配置详细信息。用于错误报告 说明请见:http://www.gnu.org/software/gdb/bugs/。 在线查找 GDB 手册和其他文档资源: http://www.gnu.org/software/gdb/documentation/。如需帮助,请键入 “帮助”。键入“apropos word”以搜索与相关的命令 “word”...从 main64 读取符号...(没有调试符号 找到)...完成。
(gdb) r 启动程序:/tmp/main64 [线程 启用使用 libthread_db 进行调试] 使用主机 libthread_db 库 “/lib/x86_64-linux-gnu/libthread_db.so.1”。 b ^C 收到的程序 信号 SIGINT,中断。 __clock_nanosleep 中的 0x00002aaaaafe092a (clock_id=1,标志=0, req=0x7fffffffdc10, rem=0x2aaaaafe092a <__clock_nanosleep>) 在../sysdeps/unix/sysv/linux/clock_nanosleep.c:41 41 ../sysdeps/unix/sysv/linux/clock_nanosleep.c:没有这样的文件或 目录。
(gdb) bt
#0 0x00002aaaaafe092a in __clock_nanosleep (clock_id=1, flags=0, req=0x7fffffffdc10, rem=0x2aaaaafe092a <__clock_nanosleep>) 在 ../sysdeps/unix/sysv/linux/clock_nanosleep.c:41
#1 0x0000000000400630 in main() (gdb)
set architecture i386 也无济于事。
更多新闻:info proc mapp 显示 x32 应用程序位于 [vvar],而 x64 应用程序位于 libc。这可以解释为什么 gdb 找不到回溯。
所以我的问题是:是否有不同版本的 libc,它在哪里工作?我正在使用 ubuntu14.04。
【问题讨论】:
-
除非你在调试系统库,否则我真的不明白你为什么要单步调试它们?
-
我不想单步执行,但我想查看调用堆栈。例如,0x55579cd9 不会告诉我我是在 sem_wait、clock_nanosleep 还是在 pthread_join 中。
-
是的,调试死锁是可怕的。但是不要尝试调试系统调用,而是尝试调试您的线程逻辑。错误就在那里。也许首先将线程数减少到只有 2 个。如果可行,请添加一个线程,直到它失败。然后开始推理可能发生的事情(或将调试信息打印到控制台或文件)。
-
这里的问题是,死锁与时间有关。当我单步执行时程序运行良好,并且可能在我插入打印件时也能正常运行。
标签: c gdb system-calls 32bit-64bit libc