【问题标题】:How to find which thread caused SEGFAULT in a post-mortem gdb session?如何在事后 gdb 会话中查找导致 SEGFAULT 的线程?
【发布时间】:2011-02-08 19:47:02
【问题描述】:

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

如果我现在对内核运行 gdb-post-mortem 分析,导致 SEGFAULT 的线程不再可见。有什么办法可以让我看到 SEGFAULT 的原因吗?

【问题讨论】:

  • 你还在处理程序中做其他工作吗?为什么不让操作系统使用其默认行为为您留下一个内核?
  • 只是创建一个 backlog 到 stderr 然后调用 abort()。
  • 请指定您的操作系统,以及您在 GDB 中观察到的确切内容。在 Linux(以及我能想到的所有其他 UNIX)上,SIGSEGV 处理程序将在首先导致 SIGSEGV 的线程中运行。如果该处理程序调用 abort(),则核心转储将包含该线程作为线程 #1,并且准确查找导致问题的指令和调用堆栈将没有问题。由于您遇到了困难,您要么在某些“奇怪”的操作系统上,要么您没有正确描述您实际观察到的内容。
  • 我在 Linux 上,特别是 Ubuntu 9.10,32 位。不,SIGSEGV 是在主线程上调用的,而段错误发生在另一个线程上。我目前无法重现该问题,因为它是迄今为止我无法重现的单一事件。

标签: c++ gdb segmentation-fault


【解决方案1】:

您可以使用命令thread apply all btthread apply all bt full 来获取所有线程的回溯。可能有用。

顺便说一句,如果你摆脱你的处理程序,你的操作系统会创建一个核心文件吗?

【讨论】:

  • 目前我使用处理程序将回溯写入标准错误,所以我有任何东西,因为我无法从核心文件中得到任何东西。我必须尝试默认处理程序是否会产生“更好”的核心转储。
  • ulimit -c unlimited 看看没有任何处理程序你会得到什么核心。
  • @skwllsp,有没有办法确切地知道哪个线程导致了 SIGSEGV?你的意思是说它实际上是不可能知道的,必须通过回溯来找到它?
  • 通常,gdb(用于分析核心文件时)使用命令bt 打印导致核心转储的线程的堆栈跟踪。这是默认行为。当核心转储不在第一个线程中时,问题实际上是关于相反的情况。这就是为什么我建议获取所有线程的回溯。
猜你喜欢
  • 2013-04-19
  • 2014-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
相关资源
最近更新 更多