次の方法で共有


実行ファイルにデバッグ情報が含まれるか確認する方法

質問

2009年6月3日水曜日 10:13

デバッグ情報をつけた実行ファイルとそうでない実行ファイルを、VisualStudioのツールのdumpbin.exeに/headersオプションを付けて実行した結果を比較したところ、Debug Directoriesの有無があることが分かりました。

この情報を元にDebug Directoriesがある場合はデバッグ情報が含まれていると判断してよいのか、それとも他に確認する方法があるのかご教示願います。

すべての返信 (7)

2009年6月3日水曜日 12:33 ✅回答済み | 2 票

それでいいと思います。
実行ファイル外の情報としては.pdbファイルがありますが、実行ファイル内の情報としてはDebug Directoryだけでしょう。
dumpbinの出力内容やバイナリエディタなどでわかりますが、PDBファイルへのfull pathが書かれていて、このpathがちょっぴり恥ずかしかったり。

PEフォーマット(EXEやDLLの形式)を理解したい、という質問ではありませんよね?


2009年6月3日水曜日 14:19 ✅回答済み | 2 票

目的を満たすには既に回答のあることで十分だと考えていますが、デバッグ情報絡みと言うことでご紹介まで。

Debug Interface Access SDK
http://msdn.microsoft.com/ja-jp/library/x93ctkx8(VS.80).aspx

シンボル情報の取得等、COMベースで提供されており、これをうまく利用すると、実行可能ファイル名からPDBファイル名等を得ることはできます。

# これを使って、デバッグ情報ありの設定でリリースしていないかチェックするツールを会社で作ったなぁ。
# 会社で作ったので公開できませんが…。

解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。


2009年6月3日水曜日 14:56 | 1 票

PEフォーマットに関してはDbgHelpとかもありますし。
というかPEヘッダを見るだけならGetModuleHandle()もしくはLoadLibrary()でimage base addressが取れます。

# てきとーなコメントですみません。


2009年6月4日木曜日 0:24

> 佐祐理さん

回答ありがとうございます。

やはりDebug Directoryだけですか。

目的を明確にしてなかったのですが、誤ってデバッグ情報の入った実行ファイルを配布しないためにチェックしたかったのです。

Debug Directoryの有無でチェックできるのであれば、それで目的は達成できます。

> PEフォーマット(EXEやDLLの形式)を理解したい、という質問ではありませんよね?

はい、今回はそのような質問ではありませんでした。

DbgHelpも参考にさせていただきます。

> Azuleanさん

回答ありがとうございます。

> # これを使って、デバッグ情報ありの設定でリリースしていないかチェックするツールを会社で作ったなぁ。

目的はまさにそれです!!!

Debug Interface Access SDKを利用してチャレンジしてみます。

皆さん、ありがとうございました。


2009年6月4日木曜日 3:49 | 1 票

x64には未対応ですが、Debug Help Library(DbgHelp)で

  PLOADED_IMAGE image = ImageLoad( "test.dll", NULL  );
  if( image ){
    printf( "debug info size: %d\n", image->FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size );
    ImageUnload( image );
  }

このサイズ >0でデバッグ情報あり、でした。
# 私はもっと面倒くさい判定方法してました orz

ところでデバッグ情報の実体はPDBファイルに書かれていて、EXE / DLL内にはPDBファイルへのパスぐらいしか書かれていません。サイズにして数十バイト程度です。
ダンプ解析なども考えておられましたら、デバッグ情報を残しておいた方がいいのでは、とも思います。

それとは別に、デバッグ情報が入るかどうかはコンパイルオプション(リンカオプション)で決まるわけですから、そちらをプロパティシート などで制御してしまってもいいように思います。


2009年6月4日木曜日 5:29

> 佐祐理さん

回答ありがとうございます。

早速5行のプログラムを試したところ、うまくいきました。

まさかこれほど簡単にいくとは思っていませんでした(^^

また、SDKにはDllNameと書いてありますが、EXEでもOKでした。

Debug Interface Access SDKの方でも試しているので、さまざまな条件を考慮した上でどちらを利用するか判断したいと思います。

>ところでデバッグ情報の実体はPDBファイルに書かれていて、EXE / DLL内にはPDBファイルへのパスぐらいしか書かれていません。サイズにして数十バイト程> 度です。
>ダンプ解析なども考えておられましたら、デバッグ情報を残しておいた方がいいのでは、とも思います。

それも一つの案ですね。ダンプ解析などで利用するときにはぜひ活用させていただきます。

アドバイスありがとうございました。


2009年6月4日木曜日 10:19

帰宅したので、もっと面倒くさい方法を見てみました。
現在実行中のEXEについて出力します。

    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)GetModuleHandle( NULL );
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)( (LPBYTE)pDos + pDos->e_lfanew );
    printf( "debug info size: %d\n", pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size );

…実はDbgHelpすら必要なかったりします。
これもx64には対応していません。x86とx64で構造体のサイズが違いますので、きちんとコード分岐する必要があります。
Debug Interface Access SDKがその辺りを面倒見てくれるなら、そっちで楽した方がいいかもです。