・現在、SH3(SH7709S)を使ったシステムで、数か月に1回、不定期にCPUの例外処理が発生しています。
例外が発生した場合 spc等の情報をログに残すようにしています。その情報をもとに
原因や例外の発生場所を探しているのですが、メモリダンプして下記SPCのアドレスを検索しても
ヒットしません。(メモリマップ上に存在しないアドレスのため)
・このあと、どのように調査や対策をしたらよいのか途方に暮れている状況です。
どなたか少しでも参考になる方法がありましたら教えて下さい。
(例外は工場現場でしか発生しないため、デバッガを接続して調査することができません)
(メモリマップ)
ROM(FMEM) 0000_0000~0007_FFFF
SRAM 0C00_0000~0C0F_FFFF
(例外事例)
spc=3A5D3869,ssr=0100,evnt=00E0 (命令アドレスエラー)
spc=07070707,ssr=0101,evnt=00E0(命令アドレスエラー)
spc=06060870,ssr=0100,evnt=0180(一般不当命令)
(参考)
ソースコードの解析ではスタックや配列のオーバーフローが起きそうな箇所は見つかりませんでした。
各種測定器でノイズを測るとほかの正常なシステムと同等レベルでした。
他に必要な情報がありましたらご連絡ください。
> ・オーバーフロー等の可能性のあるソースコードに、オーバーフローしないよう条件文を追加することとしました。
問題の原因を突き止めて解決することが正解であり、現象が表れなくすることは原因の特定からは遠ざかる方向なので悪手ですね 。
机上で特定できない論理バグはそうあるものではないと思います。コードの見直しが重要です。可能であれば、開発者チーム外のメンバーによる見直しができれば問題の発見に役立つ可能性があります。同じチームの開発者による見直しであれば特定の勘違いや思い込みが盲点となっていることはあり得ます。
> ・例外発生時にSPCを保存していますが、どこの関数から飛んできたかがわからないため、バグの発見がいまだにできない状況です。例外時にどこの関数から飛んできたかある程度推定できる方法がありましたら、アドバイスいただけないでしょうか?
各関数の先頭や処理の途中途中で例外処理が発生した場合でも破壊されないRAMの領域に関数名や行番号を記録する命令を本来の処理の邪魔にならない程度に忍ばせておき、例外処理が発生した場合にそれら記録した内容を不揮発メモリやネットワークにダンプするコードを組み込めば、どこまで動作した後で例外処理が発生したかは判定することが可能となります。スタック領域の前後に番兵を置き、それが破壊されないことを監視することも有用でしょう。