Win32デバッグ(4)・・・デバッグ情報(Borland/CodeGear編)
今回は具体的にデバッグ情報の中身を実際に覗いてみる
。覗いてみると宣言するように、デバッグ情報の構造やファイルフォーマットなどの詳細まで書くと確実に倒れる
ので、あくまでイメージを掴むために覗くだけにする。ははは・・。というより、基本的にファイルフォーマットはコンパイラなどの開発環境のメーカーによってその製品のバージョンアップ時に改訂されることがあるので、デバッグ情報にアクセスするためのインターフェースだけを公開し、フォーマットの詳細は公開しないのが現在の流れであるようなので、フォーマットの詳細は知りません
。
また、Microsoftの開発ツールによって生成されるデバッグ情報はMicrosoftのよって公開されているDbgHelpライブラリもしくはDIA(Debug Interface Access) SDKを使ってアクセスできるので、詳細はMSDNを参照ということで。DbgHelpライブラリはOSインストール時にインストールされるが、DIA SDKはデフォルトでインストールされていないので、使用する場合には、Visual Studioの統合開発環境をインストールするか、もしくは、再配布可能パッケージvcredist_x86.exeをインストールし、COMサーバーなのでmsdiaXX.dll(XXは80とか90)をregsvr32.exeなどでシステムに登録する必要がある。
ここではタイトルにもあるように自分が使っているBorland/CodeGearの開発ツールiよって生成されるデバッグ情報の中身を覗いてみるのであるが、DelphiのIDEに統合されている統合デバッガが利用しているデバッグ情報にアクセスするためのAPIが公開されていないのである。ガーン
。
ということ終了・・って事になるなら、普通は初めからこんなタイトルの記事を書かない事からも分かるように、ここでは、TD32デバッグ情報と呼ばれるデバッグ情報を生成でき、また、アクセスするためのAPIも公開されているのでその中身を見てみる。歴史は詳しくわからないが、TD32デバッグ情報はTurbo Debuggerと呼ばれる社名もまだBorlandの頃の古いデバッガで利用していたデバッグ情報の事だと思う・・・
まず、デフォルトではTD32デバッグ情報は生成されないので、TD32デバッグ情報の生成の仕方から。
適当なプロジェクトを作成して、「プロジェクト」メニューから「オプション」メニューを選択、そして、「リンカ」設定を選択、
上の画像のように「EXEとDLLのオプション」の「TD32デバッグ情報を含める」にチェック。
以上であるが、「コンパイラ」設定の「デバッグ情報」「ローカルシンボル」あたりのオプションも生成されるTD32デバッグ情報の詳細レベルの影響するので・・
で、プロジェクトをコンパイルする。これによってTD32デバッグ情報を含んだ実行可能ファイルが生成される。
TD32デバッグ情報にアクセスするためのAPI(BorDebug.DLLとそのCヘッダ)はCodeGearの以下のサイトからダウンロードできる。
また、BorDebug.DLLの説明とDelphi用のヘッダファイルは以下のサイトからダウンロードできる。
英語の文書を読むのが苦にならない人は上記のサイトからダウンロードできるPDFファイルとCヘッダのコメント読んだ方が手っ取り早いので・・![]()
でいよいよ、実際にTD32デバッグ情報を覗いてみるのだが、そのためのツールTD32Scannerを作ってみた(製品に付属のTDUMP.EXEを使えば、中身をダンプできるのであるが、後でBorDebug.DLLを使ってプログラムからアクセスしたいので、その使い方を覚えるために作ってみた
)。実行画面は次の通り。
左側の「SubSection Headers」ウィンドウにはTD32デバッグ情報に含まれるサブセクションのヘッダ一覧が表示されている。最初にデバッグ情報の構造やファイルフォーマットまで詳細に書かないと述べたが、話を進めるために最低限の事は書こうと思う。、まずは、サブセクションから。サブセクションとはTD32デバッグ情報に含まれる論理的な情報のグループのことで、サブセクションに含まれる情報によって、次のタイプに分けられる。
- Module
- SrcModule
- AlignSym
- GlobalSym
- GlobalPub
- Names
- GlobalTypes
- Browse
順にこれらのうちのいくつかを見ていくが、その前に今回は、次の簡単なコンソールプログラムのTD32デバッグ情報を例にとり話を進めるので・・
1×1から9×9まで計算するプログラムで、Multiplyは2つの値を積を返す関数である。
まずは、Moduleサブセクション。Moduleサブセクションはモジュールに関する情報が格納されているサブセクションである。Delphiでいうとモジュールは.DCU(Delphi Compiled Unit)ファイルに相当する。上の画像より今回の例ではModuleIndexが1から7までの7つのModuleサブセクションがあることがわかる。「SubSection Headers」ウィンドウのグリッドからModuleIndexが7のModuleサブセクションをダブルクリックしてその詳細を見てみると、次のようになる。
上の画像のNameIndexより、モジュールTD32Target.DCUに関するModuleサブセクションであることが分かる。
また、Segmentsグリッドにはそのモジュールに含まれるコードが最終的な実行可能ファイルのどこに含まれているかの対応関係を表す情報が表示されている。
Windowsにおける実行可能ファイルのフォーマットであるPE(Portable Executale)フォーマットの場合、コンパイラによって生成される機械語命令は最終的にはセクションと呼ばれるブロックに格納されるが、先ほどのSegmentsグリッドのSegment列はそのセクションのインデックスを表す。
この事から、先ほどの画像より、例えば、TD32Target.DCUに含まれるコードがセクションインデックス1の(コード)セクションのオフセット0x00007070からオフセット0x00007213までの420バイトの領域に含まれている事が分かる(ややこしいが、TD32Scannerにおいて、Segmentと表記されているものは、PEファイルにおけるセクションのインデックスを表すので注意・・・・
)。
次に、ソースに関する情報が格納されているSrcModuleサブセクション。ここでは、TD32Target.DCUの元になるソースに関する情報を見るとして、「SubSection Headers」ウィンドウのModuleIndexが7のSrcModuleサブセクションをダブルクリックする。
SourceFilesグリッドより、TD32Target.DCUは1つのソースファイルTD32Target.dprから構成されていることが分かる。
次に、ローカルシンボルに関する情報が格納されているAlignSymサブセクション。SrcModuleの時と同じように、TD32Target.DCUに含まれるシンボルを見るとして、ModuleIndexが7のAlignSymサブセクションをダブルクリックする。
Symbolsグリッドには含まれるすべてのシンボルが列挙されている。SymbolKindはシンボルの種類を表すがその一覧はここでは省略するとして、ここではローカルプロシージャを表すシンボルであるLPROC32シンボルの詳細を見てみる。例えば、上の画像において、上から2つめのLPROCシンボルを選択してみる。
NameIndexより自分で定義したMultiply関数のシンボルである事が分かる。また、Segment、Offset、Lengthより、この関数の機械語命令のコードがセクションインデックス1のセクションのオフセット0x00007070から0x0000708Bまでの28バイトの領域に含まれていることが分かる。
とまぁ、残りは省略するが、デバッグ情報の内容とはこんな感じなのである。
作ったTD32ScannerはSkyDriveにアップロードしておいた。現在、GlobalTypesサブセクションにはしっかり対応していないので
。型に関する情報多すぎ
。
ふぅ。
| 固定リンク
「Delphi」カテゴリの記事
- Win32デバッグ(12)・・・SEH(Structured Exception Handling)(2009.10.07)
- ODBCヘッダー(2009.09.24)
- Win32デバッグ(4)・・・デバッグ情報(Borland/CodeGear編)(2009.05.10)
- テスト投稿(2008.09.05)
- コンテナ(2009.04.28)
「Windows」カテゴリの記事
- Win32デバッグ(12)・・・SEH(Structured Exception Handling)(2009.10.07)
- Win32デバッグ(11)・・・番外編(2009.10.06)
- Win32デバッグ(10)・・・泣(2009.09.30)
- 間隔(インターバル)型の続き(2009.08.23)
- Win32デバッグ(9)・・・逆アセンブラ(2009.08.15)
「デバッグ」カテゴリの記事
- Win32デバッグ(12)・・・SEH(Structured Exception Handling)(2009.10.07)
- Win32デバッグ(11)・・・番外編(2009.10.06)
- Win32デバッグ(10)・・・泣(2009.09.30)
- Win32デバッグ(9)・・・逆アセンブラ(2009.08.15)
- Win32デバッグ(8)・・・そして(2009.08.14)








コメント