2012-02-13 59 views
2

我们正在跟踪的错误发生在特定的基于VxWorks的嵌入式环境中(供应商修改了未知的扩展内容,并提供了大部分VxWorks内容的抽象层)。我们有两个任务按不同的优先级运行,大约每100ms执行一次。具有较高优先级只计算增加的​​任务计数的整数(只所以做任何事情),而与低优先级的任务创建一个字符串,像这样:如何诊断奇怪的种族条件错误?

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

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

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

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

我试着分析那里发生了什么,但我不能用调试器输入任何string-方法,并且将打印语句添加到基本字符串似乎不起作用(这是this question of mine的背景)。我的怀疑是那里有东西腐蚀了导致电源回路的堆叠。我的问题是,在旧的VxWorks版本中是否有任何可以解释的错误?如果没有,你有任何进一步的建议如何诊断?我可以进行反汇编和堆栈转储,但我也没有经验解释。任何人都可以provide some pointers

回答

0

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

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

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

+0

用'-fno-exceptions'编译没有帮助。我也无法通过手动创建'try/catch'环境并使用'new'和'delete'分配/释放内存来重现错误。 – 2012-02-14 10:09:06

0

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

该文档中提到了类似于“在没有VX_FP_TASK选项时产生的任务中执行任何浮点运算并且非常难以找到”的致命错误。现在,你可能认为你根本没有使用FP寄存器,但是C++使用它们进行了一些优化,而MMX操作(就像你可能用于你的添加那样)确实需要保存这些寄存器。