2012-02-13 10 views
2

私たちが追跡しているバグは、特定のVxWorksベースの組み込み環境内で発生します(ベンダーは不明な拡張機能に変更し、VxWorksの多くの抽象レイヤーを提供します)。私たちは、約100msごとに実行する、異なる優先度で実行する2つのタスクを持っています。間の共有状態が存在しないことを奇妙な競合状態のバグを診断するにはどうすればいいですか?

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

注:優先順位の低いこのように、文字列を作成して高い優先度は、単にタスクながら、(それは何もしないだけに)整数をカウントアップ追加カウントとタスクこれらの仕事はまったくありません。これらはどちらも自動ローカル変数でのみ動作します。

各実行では、各タスクで100回実行されるため、競合状態が発生する確率は高くなります。アプリケーションは2〜3分間正常に実行され、その後、CPU負荷が5%から100%になり、そこにとどまります。文字列を作成したタスクでは、全体の時間が使用されているように見えます。これまでのところ、std::stringを使用せずに動作を再現することはできませんでした。

私たちはGCC 4.1.2を使用し、VxWorks 5.5で動作しています。プログラムはPentium IIIで実行されます。

私はデバッガでstringのメソッドを入力することはできませんし、print-statementsを基本文字列に追加することはできません(これはthis question of mineの背景です)。私の疑惑はそこにあるものがスタックを破壊して電源ループを引き起こすということです。私の質問は、これを説明することができる古いVxWorksのバージョンには何らかのエラーがあるのでしょうか?そうでない場合、これを診断する方法をさらに提案していますか?私は逆アセンブリとスタックダンプを得ることができますが、私はどちらかの解釈に経験がありません。誰でもprovide some pointersできますか?

答えて

0

私が覚えている場合、vxWorksはスレッド固有のメモリロケーション(または場合によってはただ1つのロケーション)を提供します。この機能を使用すると、タスクスイッチによって自動的にシャドウされるメモリの場所を指定できるため、スレッドが書き込むたびに値がタスクスイッチ間で保持されます。追加のレジスタの保存/復元のようなものです。

GCCは、例外スタックを追跡するために、スレッド固有のメモリロケーションの1つを使用します。別の方法で例外を使用しない場合でも、std::stringコンストラクタが呼び出す可能性のあるnewなどの状況があり、このスタックを操作する環境のように暗黙的にtry/catchを作成します。もっと古いバージョンのgccでは、名目上例外処理を使用していなかったコードを使っています。

この場合、解決策は-fno-exceptionsでコンパイルしてその動作をすべて排除し、その後問題は解決しました。

+0

'-fno-exceptions'を使ってコンパイルするのは役に立ちませんでした。私は手動で 'try/catch'環境を作り、' new'と 'delete'を使ってメモリを割り当て/解放することでバグを再現することもできませんでした。 –

0

説明不能な動作のVxWorksシステムで奇妙な競合状態が発生すると、私の最初の考えは常に「VX_FP_TASK again strike!」です。まずチェックする必要があるのは、taskSpawnのVX_FP_TASKフラグを使ってスレッドが作成されているかどうかです。

ドキュメントには、「VX_FP_TASKオプションなしで生成されたタスクで浮動小数点演算を実行するのは致命的であり、見つけにくい」と書かれています。今では、FPレジスタをまったく使用していないと思うかもしれませんが、C++はいくつかの最適化のためにそれらを使用し、MMX演算はそれらのレジスタを保持する必要があります。

関連する問題