【问题标题】:Segmentation fault only when running on multi-core仅在多核上运行时出现分段错误
【发布时间】:2010-12-17 08:19:30
【问题描述】:

我正在使用一个多线程的 c++ 库,并且可以使用变量来设置工作线程的数量。该库使用 pthreads。当我在使用 3 个或更多线程的四核机器上运行作为库测试提供的应用程序时,就会出现问题。应用程序以分段错误运行时错误退出。当我尝试在库的某些部分插入一些跟踪“cout”时,问题得到解决,应用程序正常完成。 在单核机器上运行时,无论使用多少线程,应用程序都正常结束。

我怎样才能找出问题接缝的位置?

这是一种同步错误吗?我怎样才能找到它?有什么工具我也可以使用检查代码吗?

【问题讨论】:

  • 从您的描述来看,这似乎是一种竞速状态,其中一个线程很可能正在尝试访问尚未被另一个线程初始化的内存。您可能想尝试在调试器下重现它并查看故障点的调用堆栈。
  • 我真的不知道故障点在哪里,因为在调试模式下问题不会出现。
  • 有些编译器在调试模式下会用它们的默认值初始化变量,所以在调试模式下可能不会发生这种情况
  • 您可以在优化时包含调试符号,并且可以附加调试器,而不管其中任何一个。 “调试模式”用词不当。
  • 当您获得 SEGFAULT 时,您可以让系统转储程序的核心,然后调试器可以加载该核心。不同的系统使用不同的方法来表示需要核心文件。但通常它就像设置环境变量一样简单。有关详细信息,请查看您的系统文档。

标签: c++ multithreading segmentation-fault multicore


【解决方案1】:

听起来您使用的是 Linux(您提到了 pthreads)。您是否考虑过运行valgrind

Valgrind 具有用于检查数据竞争条件 (helgrind) 和内存问题 (memcheck) 的工具。 Valgrind可能会在debug模式下发现这样的错误,而不需要产生release模式产生的crash。

【讨论】:

  • 我用过 helgrind。它表明在代码的串行部分中运行的部分中存在一些错误作为竞争条件,它还表明并行部分中存在一些相同的错误,如下所示,但我不明白它的含义。 -------------------------------------------------------- ==28556== 这个与线程 #6 ==28556== 在 0x806A3ED 的先前读取的大小 4 冲突:Population::GaSortedGroup::GetAt(int) const (SortedGroup.h:181) .....(方法调用的顺序)
  • 竞争条件是指您有两个或多个线程在(可能)同时查看同一位数据。通常共享的可变数据应该受到互斥体的保护,因此您不能(例如)让一个线程在另一个线程更新数据时读取数据。这会给您带来陈旧的数据并导致问题。
【解决方案2】:

一些常规调试建议。

  1. 确保您的构建包含符号(使用 -g 编译)。此选项与其他构建选项正交(即,使用符号构建的决定与优化级别无关)。
  2. 拥有符号后,请仔细查看发生段错误的调用堆栈。为此,首先确保您的环境配置为生成核心文件(ulimit -c 无限制),然后在崩溃后,在调试器中加载程序/核心(gdb /path/to/prog /path/to/core) .一旦您知道代码的哪一部分导致了崩溃,您就应该更好地了解出了什么问题。

【讨论】:

  • 我对核心是什么一无所知。我不知道/path/to/core。你能解释得更详细些吗?
  • 好吧,你很快就会发现'gdb' :)
【解决方案3】:

您正处于竞争状态。
多个线程在同一资源上进行交互。
有很多可能的罪魁祸首,但没有来源,我们所说的一切都是猜测。

你想创建一个核心文件;然后使用核心文件调试应用程序。这会将调试器设置为应用程序崩溃时的状态。这将允许您检查变量/寄存器等。

如何做到这一点取决于您的系统。

Google 很快发现了这一点:

http://www.codeguru.com/forum/archive/index.php/t-299035.html

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-30
    • 2013-05-04
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多