Oracle® Solaris Studio 12.4: dbx コマンドによるデバッグ

印刷ビューの終了

更新: 2015 年 1 月
 
 

FPE シグナルのトラップ (Oracle Solaris のみ)

浮動小数点や整数の算術演算によって、オーバーフローや 0 による除算などの例外が発生する場合があります。このような例外は多くの場合、サイレントです。つまり、例外を発生させた操作の結果としてシステムが (NaN などの) 妥当な答えを返します。そのため、これらの例外は dbx には認識されません。

この例外をサイレントではなく、トラップを発生させるように調整することができます。その場合、オペレーティングシステムがそのトラップを SIGFPE に変換してプロセスに配信すると、dbx はこのシグナル配信をインターセプトできます。次の点に注意してください。

  • F77 は、デフォルトではどの浮動小数点例外でもトラップしません。

  • F95 は、デフォルトでは無効なオペランド、0 による除算、およびオーバーフローの例外でトラップしますが、アンダーフローと不正確の例外ではトラップしません。

  • C および C++ は、デフォルトでは浮動小数点例外ではトラップしません。

  • 整数オーバーフローが SIGFPE を暗黙的にトリガーするプロビジョニングはありません。SPARC では、TVS (trap-on-overflow-set) アセンブリ命令を使用できます。SPARC または Intel では、類似の branch-on-overflow-set 命令を使用できます。

例外の原因を見つけ出すためには、例外によって SIGFPE シグナルが生成されるように、トラップハンドラをプログラム内で設定する必要があります

    次のものを使用してトラップを有効にすることができます。

  • fpsetmask – この関数は、トラップの有効化を厳密に制御します。fpsetmask(3C) のマニュアルページを参照してください。

    例:

    #include <ieeefp.h>
        int main() {
        fpsetmask(FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP);
        ... 
  • ieee_handler – Fortran には、psetmask(3c) の正確な類似関数はありません。代わりに、次のようにデフォルトの動作を確立することによって、トラップを有効にすることができます。

    例:

        integer*4 ieeer
        ieeeer  = ieee_handler('set', 'common', SIGFPE_DEFAULT)

    詳細については、ieee_environment(3f) および ieee_handler(3m) のマニュアルページを参照してください。

  • -ftrap コンパイラフラグ – このタグは、fpsetmask()() と同様に、トラップの有効化を厳密に制御します。Fortran 95 の場合は、f95(1) のマニュアルページを参照してください。

前に説明した方法のいずれかを使用して浮動小数点トラップハンドラを有効にすると、ハードウェア浮動小数点ステータスレジスタ内のトラップ許可マスクが設定されます。このトラップ許可マスクにより、実行中に例外が発生すると SIGFPE シグナルが生成されます。

fpsetmask()() または ieee_handler()() の呼び出しを挿入するか、トラップハンドラを使用してプログラムをコンパイルしたら、そのプログラムを dbx にロードします。SIGFPE は、Oracle Solaris Studio 12.4 の時点ではデフォルトで捕獲されます。古いバージョンの dbx では、このシグナルが引き続き catch リスト内にあることを確認してください。

(dbx) 
catch FPE

catch FPE と同様の機能を持つ dbx の catch コマンドの代替コマンドを使用して fpsetmask()ieee_handler() のパラメータを次のように調整することによって、どの特定の例外が表示されるかをさらに調整できます。

(dbx) stop sig FPE
(dbx) ignore SIGFPE #don't catch it twice

次のコードを使用すると、さらに詳細に制御できます。

stop sig FPE subcode

ここで、subcode には次のいずれかを指定できます。

FPE_INTDIV

0 による整数除算。

FPE_INTOVF

整数オーバーフロー。

FPE_FLTDIV

0 による浮動小数点除算。

FPE_FLTOVF

浮動小数点オーバーフロー。

FPE_FLTUND

浮動小数点アンダーフロー。

FOE_FLTRES

浮動小数点の結果不正確。

FPE_FLTINV

浮動小数点演算が無効です。

FPE_FLTSUB

添字が範囲外です。

例外の発生場所の判定

FPE を catch リストに追加後、dbx でプログラムを実行します。トラップしている例外が発生すると、SIGFPE シグナルが生成され、dbx はプログラムを停止します。次に、dbxwhere コマンドを使用して呼び出しスタックをトレースすることにより、例外が発生したプログラムの特定の行番数を見つけることができます。

例外処理の原因追求

SPARC 上の例外の原因を特定するには、regs -f コマンドを使用して浮動小数点状態レジスタ (FSR) を表示します。 このレジスタの発生した例外 (aexc) フィールドと現在の例外 (cexc) フィールドを確認します。これらのフィールドには、次の浮動小数点例外条件のビットが含まれています。

  • 無効なオペランド

  • オーバーフロー

  • アンダーフロー

  • 0 による除算

  • 結果不正確

Intel では、浮動小数点ステータスレジスタは x87 の場合は fstat、SSE の場合は mxcsr です。

浮動小数点状態レジスタの詳細については、『SPARC アーキテクチャーマニュアル バージョン 8』(V9 の場合はバージョン 9) を参照してください。詳細な説明と例については、Oracle Solaris Studio 12.4: 数値計算ガイド を参照してください。