削除するパブリック シンボルの選択
PDBCopy には-f オプションと -F オプションが用意されているため、ストリップされたシンボル ファイルから任意のパブリック シンボルのセットを削除し、デバッグを実行するために対象ユーザーがアクセスする必要があるシンボルのみを残すことができます。
PDBCopy の一般的な用途は、マイクロソフトがオンライン クラッシュ分析 (OCA) プログラムで使用する特別なバージョンのシンボル ファイルを作成することです。 OCA は、特定の関数を不活性として指定できます。つまり、その関数がスタック トレースで見つかった場合は無視されます。 関数は通常、重要な計算を実行しないラッパーまたは "パススルー" 関数である場合、不活性として宣言されます。 障害分析でこのような関数がスタック上に見つかった場合、この関数自体には障害が発生しておらず、スタック上の以前のルーチンから受け取った無効なデータまたは破損したデータが渡されただけだと見なすことができます。 このような関数を無視することで、OCA はエラーまたは破損の実際の原因をより適切に特定することができます。
当然ながら、"不活性" を宣言する関数は、OCA によって使用されるシンボル ファイルのパブリック シンボル テーブルに含まれている必要があります。 ただし、次の例が示すように、含める必要がある関数はこれらだけではありません。
Windows ドライバーを記述し、PDBCopy を使用して、2 つの不活性関数である FunctionOne と FunctionSix を除くすべてのパブリック シンボルをシンボル ファイルから削除すると仮定します。 クラッシュ後に FunctionOne または FunctionSix のいずれかがスタック上で見つかった場合、OCA によって無視されることが予想されます。 ドライバーの他の部分がスタック上にある場合、マイクロソフトは対応するメモリ アドレスを提供します。そのアドレスを使用することでドライバーをデバッグできます。
ただし、ドライバーが次のレイアウトでメモリを占有していると仮定します。
番地 | メモリの内容 |
---|---|
0x1000 |
モジュールのベース アドレス |
0x2000 |
FunctionOne の先頭 |
0x203F |
FunctionOne の末尾 |
0x3000 |
FunctionSix の先頭 |
0x305F |
FunctionSix の末尾 |
0x7FFF |
メモリ内のモジュールの末尾 |
デバッガーは、スタック上のアドレスを見つけると、次に低いアドレスを持つシンボルを選択します。 パブリック シンボル テーブルには各シンボルのアドレスが含まれていますが、サイズ情報は含まれていないため、あるアドレスが実際に特定のシンボルの境界内にあるかどうかをデバッガーが認識する方法はありません。
そのため、アドレス 0x2031 でエラーが発生した場合、Microsoft OCA によって実行されるデバッガーは、エラーが FunctionOne 内にあるものとして正しく識別します。 これは不活性関数であるため、デバッガーはクラッシュの原因を見つけるためにスタックを歩き続けます。
しかし、0x2052でエラーが発生した場合、デバッガーは、この関数の実際の末尾 (0x203F) を超えている場合でも、このアドレスを FunctionOne に一致させます。
そのため、ストリップされたシンボル ファイルには、公開する関数だけでなく、これらの関数の直後にあるシンボルも含める必要があります。 この例では、FunctionOne、FunctionTwo、FunctionSix、FunctionSeven を公開します。
番地 | メモリの内容 |
---|---|
0x1000 |
モジュールのベース アドレス |
0x2000 |
FunctionOne の先頭 |
0x203F |
FunctionOne の末尾 |
0x2040 |
FunctionTwo の先頭 |
0x3000 |
FunctionSix の先頭 |
0x305F |
FunctionSix の末尾 |
0x3060 |
FunctionSeven の先頭 |
0x7FFF |
メモリ内のモジュールの末尾 |
ストリップされたシンボル ファイルにこれらの 4 つの関数をすべて含めた場合、Microsoft OCA 分析でアドレス 0x2052 が FunctionOne の一部として誤って処理されることはありません。 この例では、このアドレスが FunctionTwo の一部であると仮定しますが、FunctionTwo を不活性関数として OCA に登録していないため、これは重要ではありません。 重要なのは、0x2052 アドレスが不活性関数に該当しないと認識されることであり、OCA がこれをドライバー内の意味のある障害として認識し、エラーを通知できることです。
各不活性関数に続く関数名の公開を望まない場合は、各不活性関数に続くコードに重要でない関数を挿入し、これらの関数の名前をパブリック シンボル ファイルに含めることができます。 一部の最適化ルーチンはこれを変更したり、一部の関数を完全に削除したりする可能性があるため、追加された関数がバイナリのアドレス空間内の不活性関数に実際に従っていることを確認してください。