如何诊断奇怪的竞争条件错误?

时间:2012-02-13 21:03:38

标签: c++ race-condition vxworks

我们正在跟踪的错误发生在特定的基于VxWorks的嵌入式环境中(供应商修改了未知扩展的内容并提供了大部分VxWorks内容的抽象层)。我们有两个以不同优先级运行的任务,大约每100毫秒执行一次。具有较高优先级的任务简单地计数添加计数一个整数(只是它做任何事情),而具有较低优先级的任务创建一个字符串,如下所示:

std::string text("Some text");

请注意,这些任务之间没有共享状态。它们都只在自动局部变量上运行。

在每次运行中,每个任务都执行一百次,以便发生竞争条件的概率更高。应用程序运行良好几分钟,然后CPU负载镜头从5%到100%并保持在那里。整个时间似乎由创建字符串的任务使用。到目前为止,我们还没有使用std::string来重现行为。

我们正在使用GCC 4.1.2并在VxWorks 5.5上运行。该程序在奔腾III上运行。

我试过分析那里发生了什么,但是我不能用调试器输入任何string - 方法,并且将print-statements添加到basic-string中似乎不起作用(这是{的背景{3}})。我怀疑那里的东西会破坏堆栈,导致电源循环。我的问题是,旧的VxWorks版本中是否有任何已知错误可以解释这一点?如果没有,你有什么进一步的建议如何诊断?我可以得到反汇编和堆栈转储,但我也没有解释经验。任何人都可以this question of mine吗?

2 个答案:

答案 0 :(得分:0)

如果我记得的话,vxWorks提供特定于线程的内存位置(或者可能只有一个位置)。此功能允许您指定将由任务切换自动遮蔽的内存位置,以便每当线程写入时,该值将在任务切换中保留。这有点像额外的寄存器保存/恢复。

GCC使用其中一个特定于线程的内存位置来跟踪异常堆栈。即使您没有使用异常,也有一些情况(特别是new,例如std::string构造函数可能会调用),这会隐式创建try/catch类似操作此堆栈的环境。在一个更老的gcc版本中,我看到代码中出现了乱码,名义上没有使用任何异常处理。

在这种情况下,解决方案是使用-fno-exceptions进行编译以消除所有这些行为,之后问题就消失了。

答案 1 :(得分:0)

每当我在VxWorks系统中看到一种奇怪的竞争条件时,我的第一个想法就是“VX_FP_TASK再次出现!”您应该检查的第一件事是您的线程是否在taskSpawn中使用VX_FP_TASK标志创建。

文档说“在没有VX_FP_TASK选项的情况下执行任务中执行任何浮点运算是致命的,而且很难找到。”现在,您可能认为您根本没有使用FP寄存器,但C ++使用它们进行一些优化,而MMX操作(就像您可能在那里使用它们一样)确实需要保留这些寄存器。