在交互模式下运行简单程序时,使用它gdb
来定位分段错误非常简单。但是考虑我们有一个多线程程序 - 由 - 编写pthread
- 提交到集群节点(通过qsub
命令)。所以我们没有交互式操作。
我们如何定位分段错误?我正在寻找一种通用方法、程序或测试工具。我无法提供可重现的示例,因为该程序非常大,并且在某些未知情况下会在集群上崩溃。
我需要在这种困难的情况下找到问题,因为程序可以在本地机器上以任意数量的线程正确运行。
在交互模式下运行简单程序时,使用它gdb
来定位分段错误非常简单。但是考虑我们有一个多线程程序 - 由 - 编写pthread
- 提交到集群节点(通过qsub
命令)。所以我们没有交互式操作。
我们如何定位分段错误?我正在寻找一种通用方法、程序或测试工具。我无法提供可重现的示例,因为该程序非常大,并且在某些未知情况下会在集群上崩溃。
我需要在这种困难的情况下找到问题,因为程序可以在本地机器上以任意数量的线程正确运行。
“正常”的方法是让环境生成一个核心文件并获取这些文件。如果这不是一个选项,您可能想尝试安装一个信号处理程序SIGSEGV
,至少获得一个转储到某处的堆栈跟踪。当然,这会立即导致“如何获取堆栈跟踪”的问题,但这在其他地方得到了回答。
最简单的方法可能是获取核心文件。假设您有一台可以读取核心文件的类似机器,您可以使用它gdb program corefile
来调试program
生成核心文件的程序corefile
:您应该能够查看不同的线程、它们的数据(在某种程度上)等。如果您没有合适的机器,可能需要交叉编译gdb
匹配运行它的机器的硬件。
我对核心文件为空的说法有点困惑:您可以ulimit
在 shell 上设置核心文件的限制。如果核心的大小设置为零,则不应生成任何核心文件。生产一个空的似乎很奇怪。但是,如果您无法更改程序的限制,您可能只能安装信号处理程序并从有问题的线程中转储堆栈跟踪。
考虑一下,假设您可以在相应的机器上运行调试器,您也许可以让程序在信号处理程序中进入睡眠状态并使用调试器附加到它。您将确定进程 ID(使用,例如,ps -elf | grep program
),然后使用附加到它
gdb program pid
不过,我不确定如何让程序在程序中进入睡眠状态(可能SIGSTOP
为SIGSEGV
...安装处理程序)。
也就是说,我假设您尝试在本地计算机上运行您的程序......?有些问题比需要在每个节点上运行多个线程的分布式系统更为根本。显然,这不能替代上述方法。