« 2011年2月 | トップページ | 2011年5月 »

2011年4月

2011年4月 3日 (日)

Win32デバッグ(13)・・・最終章

MSDNを眺めててひょんな事から、ある事を発見し、やる気が起きたので、とりあえず、完成させました。

ということで、久しぶりにデバッグ絡みですdash

何を発見したかと言うと、デバッグ対象がマルスレッドアプリケーションの場合のブレークポイントの設定の仕方です。前に書いたようにブレークポイント例外発生時に、自分で設定したブレークポイントなら、元の命令に戻して、シングルステップ実行で実行させた後、続く、シングルステップ例外発生時に再びブレークポイントを設定するという基本的な流れは問題ないのですが、デバッグ対象がマルチスレッドアプリケーションの場合、タイミングによって、シングルステップ例外発生時にブレークポイントを再設定する前に、他のスレッドが通過してしまう可能性があるなぁdashdash・・とずっと前から気づいてはいたんですが、解決策が見つからず見なかった事にしてましたsweat02sweat02

で、先日MSDNを眺めてたらそのやり方が書いてありました。

MSDNのResumeThreadのnoteの部分です。

Note that while reporting debug events, all threads within the reporting process are frozen. Debuggers are expected to use the SuspendThread and ResumeThread functions to limit the set of threads that can execute within a process. By suspending all threads in a process except for the one reporting a debug event, it is possible to "single step" a single thread. The other threads are not released by a continue operation if they are suspended.

単純にSuspendThreadとResumeThreadを使えばよかったんですね・・ブレークポイント例外が発生したら、例外が発生したスレッド以外のすべてのスレッドに対してSuspendThreadしシングルステップ実行、そして、続くシングルステップ例外発生時に、ResumeThreadで元に戻すup

胸のつっかえが1つ取れました(これらの関数の存在は知っていましたが、デバッグの時使っていいのかな??と思ってました・・・)。

ということで、上記を組み込んだり、ソースを公開できるようクラス設計やアルゴリズムを一部見直したりして実用性は0ですが、デバッグ情報からコールツリーを生成するプログラムを完成させました。

Delphiで作ってるので、使用するデバッグ情報はTD32というものですが・・DbgHelpやDIA SDKを使えばMSVCが生成するPDBファイルなどのデバッグ情報も利用できるはずです。コールツリーを生成するためのアルゴリズムはMSVCの生成するコードでも問題ないと思うので(ルーチンはCALL命令で呼んで、RET命令でリターンするルーチンがとりあえず前提です。ジャンプ命令とかは勘弁sweat01)。

ダウンロードはSkyDriveから。 ソースコードとかもろもろついてます。

« 2011年2月 | トップページ | 2011年5月 »

自作ソフトウェア

無料ブログはココログ

メモ