如何在后期调试的gdb会话中找到导致SEGFAULT的线程?

32

在我的应用程序中,我处理 SIGSEGV 以生成回溯并调用 abort() 来产生核心转储。

如果现在我对 core 进行 gdb-post-mortem 分析,导致 SEGFAULT 的线程将不再可见。有没有什么方法可以让我看到 SEGFAULT 引起的原因?


2
你在 handler 里面还做其他的工作吗?为什么不让操作系统使用它的默认行为,为你留下一个核心呢? - Mark B
只需将后备日志创建到stderr,然后调用abort()。 - Martin C.
请指定您的操作系统,并说明您在GDB中观察到了什么。在Linux(以及我所知道的所有其他UNIX系统)中,SIGSEGV处理程序将在第一次引发SIGSEGV的线程中运行。如果该处理程序调用abort(),则核心转储将包含该线程作为线程#1,并且没有问题找到导致问题的确切指令和调用堆栈。由于您遇到了困难,要么是因为您使用了某些“奇怪”的操作系统,要么是因为您没有正确描述您实际观察到的情况。 - Employed Russian
1
我正在使用Linux,具体来说是Ubuntu 9.10,32位。不过,SIGSEGV是在主线程上调用的,而段错误发生在另一个线程上。目前我无法重现这个问题,因为它只出现了一次,到目前为止我还无法重现它。 - Martin C.
1个回答

24

你可以使用命令thread apply all bt或者thread apply all bt full来获取所有线程的回溯信息。可能会很有用。

顺便问一下,如果你去掉处理器,你的操作系统会创建一个核心文件吗?


目前我使用处理程序将回溯信息写入stderr,因为我无法从核心文件中获取任何信息。我必须尝试使用默认处理程序是否会产生“更好”的核心转储。 - Martin C.
4
ulimit -c unlimited,不设置任何处理程序,查看您将获得哪个核心。 - user184968
@skwllsp,有没有办法确切地知道是哪个线程导致了SIGSEGV?你的意思是实际上不可能知道,必须使用回溯来找到它吗? - russoue
2
通常情况下,gdb(用于分析核心文件时)使用命令bt打印导致核心转储的线程的堆栈跟踪。这是默认行为。实际上,问题是关于核心转储不在第一个线程的相反情况。这就是为什么我建议获取所有线程的回溯信息。 - user184968

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接