変な発想法 - Mobile編

Android, iPhone, iPad の裏技、Tips 大好き!

Visual Studio は c0000005 例外 (Data Abort) をキャッチしない?

先日来から、原因不明のアプリケーションエラーに悩まされていました。

意味不明のクラッシュはメモリ破壊と相場が決まってますから、スタックオーバーフローか、NULL ポインタのアクセスバイオレーションだろうとは思っていたのですが。(Windows Mobile はスタックが 64KB なので、気をつけないとスタックオーバーフローもあるんですねー。)


API 呼び出しでエラーが発生するもので、それ以上ステップインできずに、発生場所を特定できず、悩んでいました。


Visual Studio の Output ウインドウをよく見たら、情報が!

Data Abort: Thread=9672e360 Proc=80097030 'MainEVC4.exe'
AKY=00008001 PC=0002ef90(MainEVC4.exe+0x0001ef90) RA=0002e3e0(MainEVC4.exe+0x0001e3e0) BVA=20000000 FSR=00000407
Data Abort: Thread=9672e360 Proc=80097030 'MainEVC4.exe'
AKY=00008001 PC=0002ef90(MainEVC4.exe+0x0001ef90) RA=0002e3e0(MainEVC4.exe+0x0001e3e0) BVA=20000000 FSR=00000407

Data Abort は ARM でメモリの読み出しではじかれた時の例外とのこと。いわゆるアクセスバイオレーション(保護違反)ですね。

ARM: HOW TO ANALYZE A DATA ABORT EXCEPTION

さて、アクセスバイオレーションが発生していることは特定できたのですが。
どこで発生しているのか、この情報からわかるのって・・・。

Windows CE: Finding the cause of a Data Abort

そんな、やっぱ、ARM のアセンブリ言語まで下りて見ないとだめですかね・・・。orz


さらにググっていると。

Useless Inc. - Catching Data Abort Exceptions

を!
Visual Studio の [デバッグ]-[例外] を開き。[Win32 Exceptions] のツリーを展開すると。

あった、あった。確かに 「c0000005 Access violation」にチェックが付いていない!


チェックをつけて、デバッグしてみると。
見事にキャッチしてくれて、それらしいソースコードで止まってくれました!^^/


最終的に、どこで NULL ポインタ参照しているかも特定できて、無事デバッグできました。
めでたし、めでたし。


しかしなー、eMbedded Visual C++ の頃は、アクセスバイオレーション例外をデフォルトでデバッガがキャッチしてくれてたんですがねぇ。
んー、もしかして、C++ でちゃんと例外処理できるようになったので、プログラム自身で例外をキャッチできるってことですかね。(構造化例外処理、やったことないけど^^;)
ほとんどの例外にチェックがついていないのは、そのためか。


「例外」ダイアログをよく見ると、スタックのチェックもしてくれそうですねぇ。次からは、チェックつけてデバッグしよっと。

                                                                                              • -

図書館にも収録されている Windows Mobile 開発のバイブル
Windows Mobileプログラミング徹底理解