よく使われる 2 つのデバッグ用フォーマットである DWARF と STAB について詳しく学びましょう。そして DWARF フォーマットと STAB フォーマットを構成する UNIX 実行可能ファイルのデバッグ方法と分析方法について学びましょう。コンパイラーやデバッガーを扱うプログラマーにとって、また DWARF 情報や STAB 情報の読み書きに関心のあるすべての人にとって、この記事は特に興味深いはずです。

Adarsh Thampan, Development Manager, IBM

Photo of Adarsh ThampanAdarsh Thampan は 10 年の業界経験があり、IBM WebSphere Federation Server と Optim を HP Itanium プラットフォームにポーティングする作業や IBM 製品を System Z と z/OS 上の Linux にポーティングする作業に従事してきました。彼はホワイトペーパー、「Mixed Platform Stack Project: Linux on System z and IBM z/OS」の共著者です。



Suchitra Venugopal, Advisory System Analyst, IBM

Photo of Suchitra VenugopalSuchitra Venugopal はソフトウェア業界に 9 年を超える経験があり、さまざまな役割を担当してきました。彼女は主にオープン・システム技術を扱っています。彼女は IBM Optim を HP Itanium プラットフォームにポーティングする作業や zLinux 上の ISW に対するテストの自動化に従事してきました。彼女は現在、SPSS を zOS プラットフォームにポーティングする作業に従事しています。



2011年 9月 02日

概要

アプリケーションでエラーが発生した場合、バイナリー内にデバッグ情報が格納されていると、プログラマーやデバッガーはプログラム内の問題箇所を特定することや、スタック・トレースを見つけることができます。またこうしたデバッグ情報は、gdb や wdb などの一般的なデバッガー・ツールでも使用されています。デバッグ用データのフォーマットはコンパイルされたプログラムに関する情報を格納するための手段であり、この情報は上位レベルのデバッガーで使用されます。最近のデバッグ用データ・フォーマットには、ソース・レベルのデバッグを行う上で十分な情報が格納されます。

すべてのソフトウェア・コンポーネントでは、デバッガーとデバッグ情報が利用可能ですが (つまり存在していますが)、すべてのユーザーがデバッグ用データの構成内容やデータの格納方法を理解しているわけではありません。

読者がデバッグ用フォーマットを扱っている場合や、いずれかの UNIX プラットフォームで C/C++ プログラムによるデバッグの経験があり、コンパイラーやデバッガーの基本を理解している場合、あるいはフォーマットを選定しようとしている場合には、この記事が役に立ちます。

この記事では、STAB と DWARF という、よく使われる 2 つのデバッグ用フォーマットからデバッグ情報を抽出する方法について説明します。その中で、どちらがどの点で優れているかを比較します。また、実験や理解を助けるために、バイナリーから DWARF フォーマットで情報を抽出するためのサンプル・アプリケーションも用意してあります。

DWARF フォーマットと STAB フォーマットは最も広く使用されている ELF (Executable and Linking Format) です。

この記事は以下の状況に活用することができます。

  • デバッガーを使用せずにアプリケーションをデバッグし、デバッグ情報を別途抽出して別のファイルに格納したい場合。製品を本番環境に移行する際、デバッグ情報はすべてバイナリーから削除されます。デバッグ情報が削除される前に、必要なデバッグ情報を取得して別の複数ファイルに配置できると、後でアプリケーションに例外や機能停止が発生した場合、それらのファイルを使用して詳細なトレース情報を生成することができます。
  • 特定のプラットフォームに適したデバッグ用フォーマットを明らかにしたい場合。Solaris などの UNIX プラットフォームでは STAB を使用しており、HP Itanium では DWARF を使用しています。
  • 特定のバイナリーがソース・コードの正しいバージョンと対応しているかどうかを確認したい場合。例えば新しい関数をソース・コードに追加してバイナリーを作成した場合、ソース・ファイルとバイナリーが同期しているかどうかの検証が必要な場合があります。バイナリー内にあるデバッグ情報を調べることができると、同期の検証は容易です。ソース・コードが変更され、バイナリーがリビルドされた場合には、最新の変更に対応してバイナリーの内部レイアウトが変更されます。そのため、単純にデバッグ情報をチェックするだけで、バイナリーとソースが同期しているかどうかを確認することができます。この記事のサンプル・アプリケーションには、どのようなバイナリーを使用する場合にも重要となるデバッグ情報が含まれています。

デバッグ用フォーマット

デバッグ用データ・フォーマットは、コンパイルされたコンピューター・プログラムに関する情報を格納するための手段であり、上位レベルのデバッガーで使用されます。最近のデバッグ用データ・フォーマットには、ソース・レベルのデバッグを行う上で十分な情報が格納されます。

デバッグ用フォーマットにはさまざまな種類があります。よく使用されるフォーマットとして、STAB、COFF、PECOFF、OMF、IEEE695、そして DWARF の 3 つのバージョンなどがあります。では STAB と DWARF とを比較し、この両方のフォーマットからデバッグ情報を抽出する方法について調べてみましょう。


STAB

デバッグ情報のための従来のフォーマットとして、STAB (Symbol TABle: シンボル・テーブル) と呼ばれるフォーマットがあります。STAB 情報は ELF ファイルの .stab セクションと .stabstr セクションに格納されます。

STAB デバッグ用フォーマットは十分なドキュメントがない準標準フォーマットであり、デバッグ情報は COFF オブジェクト・ファイルと ELF オブジェクト・ファイルに格納されます。デバッグ情報はオブジェクト・ファイルのシンボル・テーブルの一部として格納されるため、複雑さや範囲が限定されています。それにもかかわらず、STAB は古い UNIX システムや UNIX 互換システムで、一般的なデバッグ用フォーマットとして使用されています。

一部のオブジェクト・ファイル・フォーマットでは、デバッグ情報は集合的に STAB ディレクティブと呼ばれるアセンブラー・ディレクティブの中にカプセル化されており、STAB ディレクティブは生成されるコードに散りばめられています。STAB はデバッグ情報のためのネイティブ・フォーマットであり、a.out や XCOFF などのオブジェクト・ファイル・フォーマットで格納されます。GNU ツールも COFF や ECOFF などのオブジェクト・ファイル・フォーマットで STAB を出力することができます。

アセンブラーは以下の 2 つのカスタム・セクションを作成します。

  • スタブごとに 1 つの構造、という固定長構造の配列を含む .stab と、
  • .stab セクションのスタブに参照される可変長ストリングをすべて含む stabstr です。

STAB バイナリー・データのバイト順はオブジェクト・ファイルのフォーマットに依存します。

プログラムの構造

STAB によってエンコードされるプログラム構造の要素には、メイン関数の名前、ソース・ファイルとインクルード・ファイルの名前、行番号、プロシージャーの名前と型、コード・ブロックの先頭と最後が含まれています。

ほとんどの言語では、メイン・プログラムに任意の名前を使用することができます。N_MAIN という STAB のタイプはデバッガーに対し、このプログラム内で使用されるメイン・プログラムの名前を伝えます。重要なのはストリング・フィールドのみです。このストリング・フィールドはメイン・プログラムの関数名です。ほとんどの C コンパイラーは、デバッガーではメイン・プログラムの関数名は main であると想定しているとみなし、この STAB を使用しません。しかし一部の C コンパイラーはメイン関数として N_MAIN STAB を出力します。

どの STAB よりも前に、ソース・ファイルを規定する STAB がなければなりません。この情報は N_SO というタイプの STAB のシンボルに含まれています。ストリング・フィールドにはファイルの名前が含まれています。シンボルの値は、そのファイルに対応するテキスト・セクション部分の開始アドレスです。

N_SLINE シンボルはソース行の開始を表します。desc フィールドには行番号が含まれ、また value には、そのソース行が開始される場所のコード・アドレスが含まれています。ほとんどのマシンの場合、このアドレスは絶対アドレスです。各セクションにある STAB の場合には、アドレスは N_SLINE シンボルが発生する関数に対する相対アドレスです。

その後にあるすべての STAB では、通常は関数に対して N_FUN というシンボル・タイプを使用します。

一般的なセクションとして、その他に以下のようなものがあります。

  • N_SLINE、N_XLINE — 行番号
  • N_LBRAC — 左括弧、関数の開始
  • N_RBRAC — 右括弧、関数の終了
  • N_SOL — このバイナリーに含まれるすべてのファイル

DWARF

DWARF (Debug With Arbitrary Record Format) は STAB よりも新しい、ELF ファイル用のフォーマットです。DWARF は STAB の欠点を解消するために作られたフォーマットであり、C の場合のように、データの構造、データ変数の動き、複雑な言語構造を STAB よりも詳細かつ簡潔に記述することができます。デバッグ情報はオブジェクト・ファイルの複数セクションに格納されます。DWARF は実行可能プログラムとソースとの関係を、デバッガーが十分効率的に処理を行える方法で簡潔に表現しています。

デバッグ情報はツリーとして表現されるため、デバッグ情報エントリーの所有関係が自然に表されます。ツリーのノードはデバッグ情報エントリーそのものです。どのノードの場合にも、ノードの子エントリーはそのノードが所有するデバッグ情報エントリーに正確に一致しています。ツリー自体は接頭辞の順にフラットに表現されます。各デバッグ情報エントリーは、「子エントリーあり」または「子エントリーなし」として定義されます。「子エントリーなし」としてエントリーが定義される場合には、そのエントリーに物理的に続くエントリーは、その前にあるエントリーの兄弟です。「子エントリーあり」としてエントリーが定義される場合には、そのエントリーに物理的に続くエントリーは、その前にあるエントリーの最初の子です。それ以外に親エントリーに子がある場合には、それらの子は最初の子の兄弟として表現されます。兄弟エントリーのチェーンはヌル・エントリーによって終了します。

DIE (デバッグ情報エントリー)

DWARF で記述するための基本エンティティーは、DIE (デバッグ情報エントリー: Debugging Information Entry) です。DIE には、その DIE によって記述する内容を規定するタグと、詳細を表現し、そのエンティティーをさらに詳しく記述する属性のリストがあります。DIE は (先頭の DIE を除き) 親 DIE に含まれ (つまり親 DIE に所有され)、兄弟 DIE または子 DIE を持つ場合があります。属性には、さまざまな値が含まれる可能性があります。例えば、(関数名などの) 定数、(関数の開始アドレスなどの) 変数、あるいは (関数の戻り値の型に対する参照などの) 別の DIE への参照などが含まれる可能性があります。

CU (コンパイル単位)

CU (コンパイル単位) は DIE の 1 つのタイプです。コンパイルの対象となるプログラムのほとんどは、複数のファイルで構成されています。プログラムを構成する各ソース・ファイルは独立にコンパイルされた後、システム・ライブラリーによってリンクされ、そのプログラムが構成されます。DWARF では、別々にコンパイルされた各ソース・ファイルをコンパイル単位と呼びます。各コンパイル単位の DWARF データは CU DIE で始まります。この DIE に含まれる内容には、コンパイルに関する一般的な情報 (ソース・ファイルのディレクトリーと名前、使用されたプログラミング言語、その DWARF データの作成者を特定するストリングなど)、行番号やマクロ情報を特定するための、DWARF データ・セクションに対するオフセットがあります。CU が連続的な場合 (つまり CU が一体としてメモリーにロードされる場合) には、その CU に対する下位メモリー・アドレスと上位メモリー・アドレスの値があります。これらの情報により、デバッガーは、どのコンパイル単位によって特定のメモリー・アドレスでコードが作成されたのかを容易に特定することができます。CU DIE はコンパイル単位を記述する DIE すべてにとっての親です。

CU は通常、1 つのリロケータブル・オブジェクト・ファイルで実行されるファイルに寄与するテキストとデータを表現します。処理済みの「インクルード・ファイル」など、いくつかのソース・ファイルから CU が作成される場合もあります。

CU のエントリーには以下のような属性があります。

  • DW_AT_low_pc 属性: この属性の値は、そのコンパイル単位に対して生成される最初のマシン命令の再配置アドレスです。
  • DW_AT_high_pc 属性: この属性の値は、そのコンパイル単位に対して生成される最後のマシン命令の後にある最初の場所の再配置アドレスです。

DIE のタイプには他にも以下のようなものがあります。

  • DW_TAG_subprogram — グローバルな、またはファイル専用のサブルーチンまたは関数
  • DW_TAG_inlined_subroutine — サブルーチンまたは関数の特定インライン・インスタンス
  • DW_TAG_entry_point — Fortranのエントリー・ポイント
  • DW_TAG_variable — 変数
  • DW_TAG_pointer_type — ポインター変数
  • DW_TAG_formal_parameter — 関数パラメーター・パック内の各引数は、このタグを持つ DIE によって表現されます。

サブプログラムの DIE は、そのサブプログラムを記述する複数の DIE を所有しています。関数に渡されるパラメーターは変数パラメーター属性を持つ変数 DIE によって表現されます。

行番号テーブル

DWARF の行テーブルには、(プログラムの実行可能部分に対する) ソース行とメモリーとの対応情報が含まれています (メモリーにはソースに対応するコードが含まれています)。最も単純な形式の場合、この行テーブルは、メモリー・アドレスを含む 1 つの列と、ソースの3 要素 (ファイル、行、列) を含む別の列から成る、マトリックスとみなすことができます。特定の行にブレークポイントを設定したい場合、ブレークポイント命令を格納するメモリー・アドレスを行テーブルから得ることができます。逆に、メモリー内のある場所でプログラムに欠陥がある場合 (例えば不適切なポインターを使用しているような場合)、そのメモリー・アドレスに最も近いソース行を調べることができます。

プログラムはノードを持つツリーとして記述されます。これらのノードはソース内のさまざまな関数、データ、型を表現し、マシンに依存しない形で簡潔な言語で記述されます。行テーブルにより、実行される命令と、それらの命令を生成したソースとの対応を知ることができます。


STAB フォーマットと DWARF フォーマットから情報を取得する

STAB と DWARF は 2 つの異なる方法でバイナリーのデバッグ情報を表現します。以下のセクションでは、STAB セクションと DWARF セクションからデバッグ情報を取得する方法について説明します。

以下に説明する方法では、各バイナリー・ファイルをスキャンしてデバッグ情報を検索し、そのバイナリーに寄与しているファイル名がどれかを判断します。各ファイルに対し、すべての関数名と、各関数に対する行番号 (最初の行番号と最後の行番号) を取得します。この情報を格納するために、リンク付きリストを使用することができます。

STAB フォーマットから情報を取得する

バイナリー・ファイルをスキャンし、そのファイル内のスタブ・セクションをチェックします。N_SOL が検出された場合、N_SOL はこのバイナリーに含まれるファイルの名前を表しており、このシンボルからファイル名を格納することができます。ファイル名を取得した後、次のステップとして、このファイル内にあるすべての関数を取得する必要があります。N_FUN は、そのスタブ・セクションにある関数を表します。N_SOL シンボル (ファイル名) の後に N_FUN シンボルを取得した場合、そのファイル名のファイルに含まれる関数を検出したということです。N_FUN から、その関数名と詳細情報を格納することができます。

この後で N_LBRAC シンボルが返される場合、N_LBRAC シンボルは左括弧と関数の開始を表します。このことから、上記の関数はここから始まると結論することができます。N_LBRAC シンボルの後には、その関数の行を表す N_SLINE または N_XLINE が続きます。このシンボルから、最初と最後の行番号、または必要な場合にはすべての行番号を格納することができます。

行番号 (N_SLINE または N_XLINE ) に対するいくつかのエントリーの後、N_RBRAC シンボルが取得されます。このシンボルを検出するということは、この関数が終了したということです。この時点で 1 セットの情報が取得されています。つまり 1 つのバイナリーに対し、含まれているファイル名の 1 つと、1 つの関数、そしてその関数の詳細が取得されています。同様に、その含まれているファイル内のすべての関数と、そのバイナリーに含まれているすべてのファイルの詳細を取得することができます。ある 1 つのバイナリー・ファイルに関するすべての情報を取得するためには、上記のステップを実行する必要があります。

シンボル・テーブルには、そのバイナリー内にあるすべてのシンボル (関数) の詳細が格納されています。リスト 1 は、単純な関数の場合に STAB フォーマットから収集する情報を図式的に表現したものです。

リスト 1. STAB タイプを表示する単純なプログラム
abcd.c    ----> Symbol is N_SOL
int function_name(int a, int b)   ------> Symbol is N_FUN
{     ----> Symbol is N_LBRAC
    int i;       ----->Symbol is N_SLINE
    i = a+b;
    return i;
} -----> Symbol is N_RBRAC

STAB フォーマットから情報を取得するアルゴリズムを表現したフロー・チャートを図 1 と図 2 に示します。

最初に次のスタブ・セクションを取得し、以下の内容を実行します。

  • そのセクションの最後に達したら、さまざまなスタブ・セクションで収集したすべての情報を統合し、1 つのデータ構造に格納します。スタブ・セクションの最後に達しない場合には、以下の処理を行います。
    1. このセクションが N_SOL であるかどうかを確認し、N_SOL である場合にはソース・ファイルの名前を抽出して Start に戻ります。
    2. このセクションが N_SOL ではない場合には、このセクションが N_UNDF/N_ENDM であるかどうかを確認します。N_UNDF/N_ENDM である場合には、現在の関数をリセットします。Start に戻ります。
    3. このセクションが N_UNDF/N_ENDM ではない場合には、このセクションが N_FUN であるかどうかを確認し、N_FUN である場合には、サブプログラムの名前を検出します。必要な場合にはスタブ番号を格納します。Start に戻ります。
    4. このセクションが N_FUN ではない場合には、このセクションが N_LBRAC であるかどうかを確認し、N_LBRAC である場合には、このセクションでサブプログラムが開始されるということです。(N_FUN セクションを既に取得してある場合には、サブプログラムの開始を意味するフラグをセットすることができます)。Start に戻ります。
    5. このセクションが N_LBRAC ではない場合には、このセクションが N_SLINE/n_XLINE であるかどうかを確認します。N_SLINE/n_XLINE は N_LBRAC の後にある行です。このセクションが N_SLINE/n_XLINE である場合には、そのサブプログラムの最初と最後の行、そして行数を格納することができます。Start に戻ります。
    6. このセクションが N_SLINE/n_XLINE ではない場合には、このセクションが N_RBRAC であるかどうかを確認します。このセクションが N_RBRAC である場合には、このセクションで関数が終了するということです。Start に戻ります。このセクションが N_RBRAC ではない場合には、このスタブ・セクションを無視し、Start に戻ります。
図 1. STAB からデバッグ情報を抽出するためのフロー・チャート
STAB からデバッグ情報を抽出するためのフロー・チャート
図 2. STAB からデバッグ情報を抽出するためのフロー・チャートの続き
STAB からデバッグ情報を抽出するアルゴリズムを示したフロー・チャートの続き

DWARF フォーマットから情報を取得する

DWARF フォーマットでは、すべての情報がツリー・フォーマットで表現されています (リスト 2)。

リスト 2. DWARF ツリー・フォーマット
COMPILE_UNIT<header overall offset = 0>:
<0><   11>	dw_tag_compile_unit		0
		DW_AT_stmt_list			0
		DW_AT_HP_actuals_stmt_list	0
		DW_AT_macro_info		0
		DW_AT_name			/usres/mainsoft-v52-orig/mw/init.C
		DW_AT_producer
		DW_AT_lanugage			DW_LANG_C_plus_plus
		DW_AT_HP_proc_per_section	yes(1)
		DW_AT_comp_dir			/home/yadvecha/ISLHPIA02/RTWIN/730/Source

LOCAL_SYMBOLS:
<1><  109>	DW_TAG_module
		DW_AT_name			/users/mainsoft-v52-orig/mw/init.C
		DW_AT_sibling			<365>
<2><  149>	DW_TAG_class_type
		DW_AT_name			setInFunc
		DW_AT_declaration		yes(1)
		DW_AT_sibling			<333>
<3><  166>	DW_TAG_subprogram
		DW_AT_name			~setInFunc
		DW_AT_HP_linkage_name		_ZN9setInFuncD1Ev
		DW_AT_declaration		no
		DW_AT_external			yes (1)
		DW_AT_accessibility		DW_ACCESS_public
		DW_AT_sibling			<229>
<4><  203>	DW_TAG_formal_parameter
		DW_AT_name			this
		DW_AT_artificial		yes (1)
		DW_AT_location			DW_OP_regx 34
		DW_AT_type			<365>

DWARF のシンボル・テーブル・セクションは STAB の場合と同じです。DWARF からデバッグ情報を抽出するためには以下の手順に従います。

バイナリー内にある各 DIE は構文解析され、CU DIE が検出されると、その CU の名前が格納されます。この名前は、このバイナリーに含まれるファイル群の名前を表します。この CU の名前が格納されるのは、この CU 内にあるすべての関数の行番号を特定するための行番号テーブルを検出するためでもあります。CU DIE の後で DW_TAG_subprogram DIE が取得された場合、このサブプログラムはこの CU DIE の下で取得されるファイルに属すということです。DW_TAG_subprogram を検出した場合には、この関数の詳細情報が格納されます。サブプログラムの属性から、このサブプログラムに対応する下位アドレスと上位アドレスを取得します。これらのアドレスは、そのサブプログラムの最初と最後に対応するアドレスを表します。これらのアドレスに対応する行番号を計算するために、この CU DIE の debug_line セクションから行バッファーを取得します。CU に対する行バッファーの各行で、下位アドレスに一致する行がないかどうかを調べ、その関数の最初の行番号を見つけます。その関数の最後の行番号は debug_line セクションから取得することができます (debug_line セクションでは、行番号のアドレスはその関数の上位アドレス以下となります)。

こうして取得された情報を基に、それらの関数のソース・ファイル名、関数名、行番号のリストを作成することができます。デバッガーはこれらの基本的な情報を使用してデバッグ動作を行います。

リスト 3 は、あるサブプログラムの DIE と、行テーブルから行番号を取得する方法を示しています。

リスト 3. DWARF の行番号マッピング
DW_TAG_subprogram DW_AT_sibling = 10
DW_AT_external = 1
DW_AT_name = strndup
DW_AT_prototyped = 1
DW_AT_type = 10
DW_AT_low_pc = 0
DW_AT_high_pc = 0x7b
Address      File      Line     Col 

0x0 	       0 	       42        0 	   
0x9            0           44        0 
0x1a           0           44        0
0x24           0           46        0 
0x2c           0           47        0 
0x32           0           49        0 
0x41           0           50        0
0x47           0           51        0 
0x50           0           53        0
0x59           0           54        0  
0x6a           0           54        0 
0x73           0           55        0 
0x7b           0           56        0 
File 0: strndup.c

このサブプログラムの開始行番号と終了行番号は、それぞれ 42 と 56 であり、それは 0x0(DW_AT_low_pc)0x7b(DW_AT_high_pc) というアドレスに対応しています。

図 3 は DWARF から情報を取得するためのアルゴリズムを表現したフロー・チャートを示しています。

最初に DWARF を初期化し、その DWARF から情報を読み取ります。DIE を得られない場合には終了します。DIE を得られた場合には、以下の処理を実行します。

  • 現在の DIE 内にある DWARF タグ名を調べます。タグが DW_TAG_compile_unit の場合には、コンパイル単位の名前を格納します。これはこのバイナリーに含まれるファイルの名前です。
  • DW_TAG_compile_unit タグがない場合には、そのサブプログラムの名前を格納します。このサブプログラムの debug_line セクションから lowpc と highpc を取得し、このサブプログラムの開始行番号と終了行番号を計算します。その情報を適切なデータ構造に格納します。
  • サブプログラム名を格納できない場合には、DIE があるかどうかのチェックから再度開始します。
図 3. DWARF からデバッグ情報を抽出するためのフロー・チャート
DWARF からデバッグ情報を抽出するアルゴリズムを示したフロー・チャート

どちらを使用すべきか

DWARF はブロック構造の拡張可能な形式により、プログラムのソースと、そのソースを実行可能コードに変換する方法を記述しています。DWARF では新しい記述の追加や記述の拡張が容易です。また、DWARF は STAB よりも高度なフォーマットであり、非連続的スコープ、スタック構造、スタック巻き戻しなど、STB では記述できない複雑な実行環境を記述する機能を備えています。一方 STAB は従来のフォーマットであり、表現力が限定されています。STAB は定義済みのシンボルや型定義に依存しており、変更や拡張は容易ではありません。

DWARF を使用することによる主なメリットして、以下の点を挙げることができます。

  • 難解なスタブを構文解析する代わりに、プラットフォームに依存しないツールによって DWARF を容易に読み取ることができます。
  • 活発に開発が行われています。
  • 拡張が容易です。そのため、高度な機能を容易に実装することができ、またコードのデバッグを最適化することができます。古いツールでは、新しいデータが無視される場合があります。

デバッグ情報を使用する新しいアプリケーションには DWARF が適しています。先ほど触れたように、DWARF は STAB よりも多くの情報を提供し、また拡張が容易です。しかしデバッグ情報が既に STAB で格納されているアプリケーションを扱う場合には、設計を変更して完全に DWARF に切り換えるだけの十分な時間がある場合を除き、STAB を使い続けた方が適切です。一般的には STAB よりも DWARF の方が望ましいと言えます。


さらに発展させる

ダウンロード・サンプルには、バイナリーから重要なデバッグ情報を DWARF フォーマットで読み取るアプリケーション (dwarfexample) が含まれています。バイナリー・ファイル (stacktrace) とソース・コード (stack_tracing.c) も用意されているため、このバイナリーを使用して「dwarfexample」アプリケーションを実行し、ソース・コード内の実際のデータ (stack_tracing.c 内にあるようなデータ) とアプリケーションの出力とを突き合わせることができます。このアプリケーションを使用して表示されるデバッグ情報には、バイナリーに含まれるソース・ファイル、各ソース・ファイル内にある関数の詳細 (関数名と行番号) などがあります。サンプル・プログラムのソース・コード (stack_tracing.c) を編集して関数を追加、削除、または行番号を変更し、その新しいバイナリーを使用してサンプル・アプリケーションを実行した場合、その出力にはサンプル・プログラムで変更された内容が反映されているのを確認することができます。

現時点で、このサンプル・アプリケーション (「ダウンロード」を参照) の出力には、バイナリー内にあるファイル、関数、行番号が表示されます。このアプリケーションを拡張すると、インライン・サブプログラムやコール・フレーム情報など、より多くの情報をバイナリーから取得できるようになります。


ダウンロード

内容ファイル名サイズ
Program to extract debug info from binariesDwarfExample.zip10KB

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=754247
ArticleTitle=デバッグ用フォーマット、DWARF と STAB
publish-date=09022011