【问题标题】:Locating segmentation fault for multithread program running on cluster定位集群上运行的多线程程序的分段错误
【发布时间】:2012-11-03 12:55:39
【问题描述】:

在交互模式下运行简单程序时,使用gdb 定位分段错误非常简单。但是考虑我们有一个多线程程序 - 由pthread 编写 - 提交到集群节点(通过qsub 命令)。所以我们没有交互操作。

我们如何定位分段错误?我正在寻找一种通用方法、程序或测试工具。我无法提供可重现的示例,因为程序非常大,并且在某些未知情况下会在集群上崩溃。

我需要在如此困难的情况下找到问题,因为程序可以在本地机器上以任意数量的线程正确运行。

【问题讨论】:

  • 您的集群有多大?你的程序需要多少个节点?
  • @SamMiller 在最多 32 个核心(线程)的一个节点上工作
  • 你有核心文件吗?
  • @SamMiller 核心文件已创建,但为空!
  • 什么操作系统?什么集群管理软件?

标签: c++ multithreading segmentation-fault cluster-computing hpc


【解决方案1】:

“正常”的方法是让环境生成一个核心文件并获取这些文件。如果这不是一个选项,您可能想尝试为SIGSEGV 安装一个信号处理程序,该处理程序至少会获得一个转储到某处的堆栈跟踪。当然,这会立即引出"how to get a stack trace" 的问题,但这已在别处得到解答。

最简单的方法可能是获取核心文件。假设您有一台可以读取核心文件的类似机器,您可以使用gdb program corefile 调试生成核心文件corefile 的程序corefile:您应该能够查看不同的线程,它们的数据(在某种程度上)等。如果您没有合适的机器,则可能需要交叉编译 gdb 以匹配运行它的机器的硬件。

我对核心文件为空的说法有点困惑:您可以在 shell 上使用ulimit 设置核心文件的限制。如果核心的大小设置为零,则不应生成任何核心文件。生产一个空的似乎很奇怪。但是,如果您无法更改程序的限制,您可能只能安装信号处理程序并从有问题的线程中转储堆栈跟踪。

考虑一下,假设您可以在相应的机器上运行调试器,您也许可以让程序在信号处理程序中休眠并使用调试器附加到它。您将确定进程 ID(使用例如 ps -elf | grep program),然后使用

附加到它
gdb program pid

不过,我不确定如何让程序在程序中进入睡眠状态(可能为 SIGSTOP 安装处理程序以用于 SIGSEGV...)。

也就是说,我假设您尝试在本地计算机上运行您的程序...?有些问题比需要在每个节点上运行多个线程的分布式系统更为根本。这显然不能替代上述方法。

【讨论】:

  • 谢谢,我更新了问题。我认为核心文件已经生成。
  • @Ali:如果生成了core文件,拿去看看是什么情况!这听起来很简单。
  • 谢谢,但阅读您提出的页面后,我不知道如何使用核心文件。对我来说没那么简单,和你一样!
  • 如果您使用gdb program corefile,您应该能够查看程序发生的位置,并在某种程度上检查变量的内容。它假设你有一个gdb 能够读取程序和程序运行的架构的核心文件。即使您没有类似的计算机,您也可以构建一个合适的 gdb 交叉版本(如果我没记错的话;我交叉编译代码并需要调试它已经有一段时间了)。
  • 另一种“正常”方法是请求交互式会话,这将使您能够访问相同类型的节点,然后以与批处理作业相同的内存和堆栈大小限制运行程序在调试器的控制下。
猜你喜欢
  • 2015-06-09
  • 1970-01-01
  • 2019-07-05
  • 2023-01-11
  • 2011-12-29
  • 2021-08-18
  • 2018-04-25
相关资源
最近更新 更多