dbx コマンドによるデバッグ

第 14 章 シグナルの処理

この章では、dbx を使用してシステムシグナルを処理する方法を説明します。dbx は、catch というブレークポイントコマンドをサポートします。catch コマンドは、catch リストに登録されているシステムシグナルのいずれかが検出された場合にプログラムを停止するよう dbx に指示します。

また、dbx コマンド contstepnext は、オプション -sig signal_name をサポートします。このオプションを使用すると、実行を再開したプログラムに対し、cont -sig コマンドで指定したシグナルを受信した場合の動作をさせることができます。

この章は次の各節から構成されています。

シグナルイベントについて

デバッグ中のプロセスにシグナルが送信されると、そのシグナルはカーネルによって dbx に送られます。通常、このことはプロンプトによって示されますが、そこでは次の 2 つの操作から 1 つを選択してください。

  1. プログラムを再開するときにそのシグナルを「取り消し」ます。これは、cont のデフォルトの動作です。これにより、SIGINT (Control-C) を使用した割り込みと再開が容易になります。

    Graphic
  2. 次のコマンドを使用して、シグナル sig をプロセスに「転送」します。


    cont -sig sig
    

    さらに、特定のシグナルを頻繁に受信する場合、そのシグナルを dbx が自動的に転送するように設定できます。次のように入力します。


    ignore sig #“ignore”
    

    ただし、sig シグナルはプロセスに転送されます。デフォルトでは、いくつかのシグナルがこの方法で自動的に転送されます。この後の「ignore」を参照してください。

システムシグナルを捕捉する

デフォルトの catch リストには、33 種類の検出可能なシグナルのうちの 22 種類が含まれています (これらの数はオペレーティングシステムとそのバージョンによって異なります)。デフォルトの catch リストは、デフォルトの ignore リストにシグナルを追加したり削除したりすることによって変更できます。

現在捕捉されているシグナルのリストを調べるには、シグナル名の引数を指定せずに、次のように入力します。


(dbx) catch

プログラムで検出された場合でも、現在無視されているシグナルのリストを調べるには、シグナル名の引数を指定せずに、次のように入力します。


(dbx) ignore

デフォルトの catch リストと ignore リストを変更する

どのシグナルでプログラムを停止するかは、2 つのリストの間でシグナル名を移動することによって制御します。シグナル名を移動するには、一方のリストに現在表示されているシグナル名を、もう一方のリストに引数として渡します。

たとえば、QUIT シグナルと ABRT シグナルを catch リストから ignore リストに移動するには、次のように入力します。


(dbx) ignore QUIT ABRT

FPE シグナルをトラップする

浮動小数点の計算が必要なコードを扱っている場合には、プログラム内で発生した例外をデバッグしなければならないことがよくあります。オーバーフローやゼロ除算などの浮動小数点例外が発生すると、例外を起こした演算の結果としてシステムが「適正な」答を返します。適正な答が返されることで、プログラムは正常に実行を続けることができます (Solaris 2.x コンピュータは、IEEE 標準のバイナリ浮動小数点演算定義の、例外に対する「適正 (reasonable) な」答を実装しています)。

浮動小数点例外に対して適正な答を返すため、例外によって自動的に SIGFPE シグナルが生成されることはありません。

例外の原因を見つけ出すためには、例外によって SIGFPE シグナルが生成されるように、トラップハンドラをプログラム内で設定する必要があります (トラップハンドラの例については、ieee_handler(3m) を参照)。ieee_handler を使用してトラップハンドラを設定すると、ハードウェア浮動小数点状態レジスタ内のトラップ許可マスクがセットされます。このトラップ許可マスクにより、実行中に例外が発生すると SIGFPE シグナルが生成されます。

トラップハンドラ付きのプログラムをコンパイルした後、そのプログラムを dbx に読み込んでください。ここで、SIGFPE が捕捉されるようにするには、dbx のシグナル捕捉リスト (catch リスト) に FPE を追加する必要があります。次のコマンドを使用します。


(dbx) catch FPE

FPE はデフォルトでは ignore リストに含まれています。

FPEcatch リストに追加後、dbx でプログラムを実行します。トラップしている例外が発生すると SIGFPE が生成され、dbx はプログラムを停止します。ここで、呼び出しスタックを (dbx コマンド where を使用して) トレースすることにより、プログラムの何行目で例外が発生したかを調べることができます。

詳細と例については、浮動小数点に関するマニュアルである『数値計算ガイド』を参照してください。

プログラム内でシグナルを送信する

dbx コマンド cont は、オプション -sig signal_name をサポートします。このオプションを使用すると、実行を再開したプログラムに対し、指定したシステムシグナルsignal_name を受信した場合の動作をさせることができます。

たとえば、プログラムに SIGINT (^C) の割り込みハンドラが含まれている場合、^C を入力することによって、アプリケーションを停止し、dbx に制御を返すことができます。ここで、プログラムの実行を継続するときにオプションなしの cont コマンドを使用すると、割り込みハンドラは実行されません。割り込みハンドラを実行するためには、プログラムに SIGINT シグナルを送信する必要があります。次のコマンドを使用します。


(dbx) cont -sig int

stop、next、detach コマンドも、-sig オプションを指定できます。

シグナルの自動処理

イベント管理コマンドでは、シグナルをイベントとして処理することもできます。次の 2 つのコマンドの結果は同じになります。


(dbx) stop sig signal
(dbx) catch signal

プログラミング済みのアクションを関連付ける必要がある場合、シグナルイベントがあると便利です。


(dbx) when sig SIGCLD {echo Got $sig $signame;}

この場合は、まず SIGCLDignore リストに必ず移動してください。


(dbx) ignore SIGCLD