Oracle® Solaris Studio 12.4: dbxtool チュートリアル

印刷ビューの終了

更新: 2014 年 10 月
 
 

コアダンプの診断

バグを見つけるには、プログラム例を再度実行して、コマンドを入力せずに Return キーを押します。

$ a.out
> display var
will display 'var'
> 
Segmentation Fault (core dumped)
$

実行可能ファイルおよびコアファイルを指定して dbxtool を起動します。

$ dbxtool a.out core

dbxtool コマンドは dbx コマンドと同じ引数を受け入れていることに注目してください。

dbxtool に、次の例のような出力が表示されます。

image:「デバッガ・コンソール」ウィンドウと strmp の呼び出し場所を表示する dbxtool ウィンドウ

    次の点に注意してください。

  • 「デバッガ・コンソール」ウィンドウに、次の例のようなメッセージが表示されます。

    program terminated by signal SEGV (no mapping at fault address)
    0xf8cfb790: strcmp+0x0170:      ld       [%ol], %gl
    Current function is Interp::find
  • strcmp() 関数で SEGV が発生していても、dbx はデバッグ情報のある最初の関数フレームを自動的に表示します。下図のように、「呼び出しスタック」ウィンドウのスタックトレースでは、アイコンの周囲を強調表示して現在のフレームを示します。

    image:アイコンの周囲を強調表示して現在のフレームを示す「呼び出しスタック」ウィンドウ

    「呼び出しスタック」ウィンドウにパラメータ名と値が表示されます。この例では、strcmp() に渡された 2 番目のパラメータは 0x0 であり、name の値は NULL です。

  • 「エディタ」ウィンドウで、95 行目のラベンダー色のストライプと三角印は strcmp() を呼び出している場所を示し、実際にエラーの発生した場所は緑色のストライプと矢印で示されます。

    image:マージンに三角印、ソースコード行にラベンダー色のストライプが表示された「エディタ」ウィンドウ

    パラメータの値が表示されない場合は、dbxenv 変数 stack_verbose.dbxrc ファイルで on に設定されていることを確認してください。ウィンドウ内を右クリックして「詳細」オプションを選択し、「呼び出しスタック」ウィンドウで詳細モードを設定することもできます。dbxenv 変数と .dbxrc の詳細は、Oracle Solaris Studio 12.4: dbx コマンドによるデバッグ の第 3 章dbx のカスタマイズを参照してください

関数は、パラメータとして不正な値を渡される場合は通常失敗します。strcmp() に渡された値を確認するには:

  • 「変数」ウィンドウのパラメータの値を確認します。

    1. 「変数」タブをクリックします。

      image:「変数」ウィンドウ

      name の値が NULL であることに注意してください。その値が SEGV の原因である可能性が高いですが、もう一方のパラメータ (*cp)->name() の値を確認します。

    2. 「変数」ウィンドウで、cp ノードを展開し、次に (cp*) ノードも展開します。この name は "quit" になっており、問題ありません。

      image:ノードが展開された「変数」ウィンドウ

    *cp ノードを展開して追加の変数が表示されない場合は、.dbxrc ファイルの dbx 環境変数 output_inherited_members がオンに設定されていることを確認します。ウィンドウを右クリックして、「継承されたメンバー」チェックボックスをオンにしてチェックマークを追加して、継承されたメンバーの表示をオンにすることもできます。

  • バルーン評価を使用して、パラメータの値を確認します。「エディタ」ウィンドウ内をクリックし、カーソルを strcmp() に渡されている変数 name の上に置きます。ヒントが表示され、name の値が NULL であるとわかります。

    image:バルーン評価のヒントを表示する「エディタ」ウィンドウ

    バルーン評価を使用すると、(*cp)->name() のような式の上にカーソルを置くこともできます。ただし、関数呼び出しを含む式のバルーン評価は次の理由で無効になります。

    • デバッグしているのがコアファイルである。

    • 「エディタ」ウィンドウにカーソルを偶然置いた結果、関数呼び出しに副作用が発生する場合がある。

name の値を NULL にすることはできないため、この不正な値を Interp::find() に渡したコードを見つける必要があります。見つけるには:

  1. 「デバッグ」->「スタック」->「呼び出し元を現在に設定」を選択するか、ツールバーの「呼び出し元を現在に設定」ボタン (Alt+Page Down) image:「呼び出し元を現在に設定」ボタン をクリックします。

    image:呼び出し元が現在のフレームとしてマーク付けされている「呼び出しスタック」ウィンドウ
  2. 「呼び出しスタック」ウィンドウで、Interp::dispatch() に対応するフレームをダブルクリックします。

    「エディタ」ウィンドウで、対応するコードが強調表示されます。

    image:未知のコードが表示された「エディタ」ウィンドウ

    このコードは未知であり、argv[0] の値が NULL であること以外に手掛かりがありません。

この問題のデバッグは、ブレークポイントとステップ動作を使用して動的に行う方が簡単である可能性があります。