多线程应用程序的核心转储只显示一个线程

时间:2010-11-02 11:23:09

标签: linux multithreading gdb

我在c ++中有一个测试应用程序,在main()中启动多个线程,然后永远在main()休眠。

其中一个线程正在做一些导致段错误的事情并且生成了一个coredump(先前已经设置了ulimit -c unlimited)。

我正在使用gdb打开核心并看到thread apply all btinfo threads我只有一个帖子(在main()中启动),这是不可能的,因为在至少main()线程也应该运行。

问题是,其余的线程如何丢失以及可能导致什么原因?

这个孤独线索的回溯似乎没问题,其中没有什么奇怪的东西。

操作系统是Red Hat Enterprise 5.3,gdb-6.8。

5 个答案:

答案 0 :(得分:3)

您只看到一个线程的原因是GDB无法“自行”区分线程,它依赖于线程库提供的外部库libthread_db

必须在调试会话开始时启用此库,以便监视线程活动(出生,死亡等),并在运行时将所有与线程相关的信息传递给GDB。

你应该能够阅读

[Thread debugging using libthread_db enabled]

当您尝试调试使用-lpthread编译的任何文件时,但在调试核心转储时GDB甚至不尝试启用libthread_db

答案 1 :(得分:1)

原来是Red Hat Enterprise 5.3中的内核错误,已在后来的Red Hat版本(5.4)中修复 - kernel-2.6.18-164.el5

http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/5/html-single/5.4_Technical_Notes/index.html

  

1.110.1。 RHSA-2009:1193:32位系统上的重要安全性和错误修复更新,某些多线程应用程序的核心转储未包含所有线程信息。 (BZ#505322)

https://bugzilla.redhat.com/show_bug.cgi?id=505322

答案 2 :(得分:0)

你真的确定这是不可能的吗?也许问题与主线程退出而不等待其他线程的事实完全相关。

答案 3 :(得分:0)

尝试在Valgrind下运行您的应用程序。 Maby这将有助于找出崩溃的原因。

答案 4 :(得分:0)

如果您没有使用alt堆栈的SIGEGV的sighandler,这是一种特殊情况,只需使用strace。

strace -f myprogram

(man strace)

(我们需要-f标志,因为在Linux中线程总是全局范围的。例如〜procs在同一个内存中运行)

这是示例输出,显示在崩溃之前退出的线程。 我强调了有趣的部分......

克隆(

附加过程28757

child_stack = 0x7fc1fc319ff0,旗帜= CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID,parent_tidptr = 0x7fc1fc31a9e0,TLS = 0x7fc1fc31a710,child_tidptr = 0x7fc1fc31a9e0)= 28757

[pid 28756] rt_sigprocmask(SIG_BLOCK,[CHLD],

[pid 28757] set_robust_list(0x7fc1fc31a9f0,0x18

[pid 28756]< ... rt_sigprocmask恢复> [],8)= 0

[pid 28757]< ... set_robust_list已恢复> )= 0

[pid 28756] rt_sigaction(SIGCHLD,NULL,{SIG_DFL,[],0},8)= 0

[pid 28757] madvise(0x7fc1fb91a000,10465280,MADV_DONTNEED

[pid 28756] rt_sigprocmask(SIG_SETMASK,[],

[pid 28757]< ... madvise恢复> )= 0

[pid 28756]< ... rt_sigprocmask恢复> NULL,8)= 0

[pid 28757] _exit(0)=?

处理28757已分离

nanosleep({1,0},0x7fffce29c4b0)= 0

rt_sigprocmask(SIG_UNBLOCK,[ABRT],NULL,8)= 0

tgkill(28756,28756,SIGABRT)= 0 --- SIGABRT(已中止)@ 0(0)---

+++被SIGABRT杀死(核心转储)+++

中止(核心倾销)

现在在输出中执行grep并查看附加vs已分离的数字。 如果你确实在退出(崩溃)时有实时线程,我会创建一个bugzilla条目(首先搜索bugzilla ofc)。