fex_set_log(3M)

名前
fex_set_log, fex_get_log, fex_set_log_depth, fex_get_log_depth, fex_log_entry - 浮動小数点例外の遡及診断のログ

形式

cc [ flag ... ] file ... -R/opt/SUNWspro/lib -L/opt/SUNWspro/lib -lm9x [ library ... ]

#include <fenv.h>

int fex_set_log(FILE *fp);

FILE *fex_get_log(void);

int fex_set_log_depth(int depth);

int fex_get_log_depth(void);

void fex_log_entry(const char *msg);

機能説明

fex_set_log(fp) は、浮動小数点例外に関連する遡及診断メッセージを、 fp で指定したファイルに記録することを有効にします。fp が NULL の場合、ログは無効になります。プログラムの起動時、ログは無効です。

fex_set_handling(3M) にリストされている 12 個の例外のいずれかが発生すると、 記録できるイベントが構成されます。ログが長くなりすぎないようにするために、ログ メカニズムは 2 つの方法で冗長なエントリを削除します。1 番目の方法では、各例外を プログラム内の「サイト」に関連付けます。サイトは、スタックトレースとともに、例外 の原因となった命令のアドレスで識別されます。特定のサイトで発生した、特定の型の 最初の例外だけが記録されます。2 番目の方法では、ある例外で FEX_NONSTOP 処理モードが有効であるとき、以前クリアしたフラグを設定した例外の発生だけが記 録されます。feclearexcept() でフラグをクリアすると、以前例外が記録 されたサイトでは発生していない例外の次の発生を記録できます。

異なる型の無効な演算例外はそれぞれ同じサイトでも記録されることに注意してくださ い。しかし、FEX_NONSTOP モードが有効である型の無効な演算例外はすべて同じ フラグを共有するために、そのフラグを設定した最初の例外だけが記録されます。 feraiseexcept() または feupdateenv() の呼び出しで無効な演算 例外が発生したとき、記録される無効な演算の型は実装によって異なります。

例外によってログエントリが作成された場合、そのエントリが作成されるのは、例外が発 生したときであり、fex_set_handling(3M) 経由で選択された任意の例外処理アク ションが行われる前です。特に、例外の結果としてプログラムが異常終了した場合でも、 ログエントリは利用できます。ログエントリは例外の型、例外の原因となった命令のアド レス、どのように処理されるか、およびスタックトレースを示します。記号が利用できる 場合は、例外の原因となった命令のアドレスとスタックトレース中のアドレスの後に、対 応する記号の名前も示します。

fex_get_log() は、現在のログファイルを戻します。

fex_set_log_depth(depth) は、すべての例外で記録されるスタックトレー スの最大の深さを depth スタックフレームに設定します。デフォルトの深さは 100 です。

fex_get_log_depth() は、現在のスタックトレースの最大の深さを戻します。

fex_log_entry(msg) は、ユーザー提供エントリをログに追加します。この エントリは、msg が指す文字列とスタックトレースを含みます。浮動小数点例外 のエントリと同様に、冗長なユーザー提供エントリは削除されます。つまり、特定のサ イトから要求した、特定の msg を持つ最初のユーザー提供エントリだけが記録さ れます。ユーザー提供エントリのために、サイトを定義できるのは、 fex_log_entry() を呼び出す関数で始まるスタックトレースだけです。

戻り値
fex_set_log は、結果的にログが有効または無効になった場合にゼロ以外の値を戻 し、そうでない場合はゼロを戻します。fex_set_log_depth は、(ログが有効であ るかどうかに関わらず) 要求したスタックトレースの深さが確立された場合にゼロ以外の 値を戻し、そうでない場合はゼロを戻します。

使用例
次の例は、sscanf() で浮動小数点オーバーフローが発生したときに生成される 出力を示しています。

    #include <fenv.h>
    #include <stdio.h>
    int
    main() {
    	double x;
    /*
     * 遡及診断のログを有効にする。
     */
    	(void) fex_set_log(stdout);
    /*
     * オーバーフローに対するデフォルトの処理を確立する
     */
    	(void) fex_set_handling(FEX_OVERFLOW, FEX_NONSTOP, NULL);
    /*
     * sscanf でオーバーフローを発生させる。
     */
    	(void) sscanf("1.0e+400", "%lf", &x);
    	return 0;
    }

上記プログラムからの出力は次のようになります。

    Floating point overflow at 0xef71cac4 __base_conversion_set_exception, nonstop mode
      0xef71cacc  __base_conversion_set_exception
      0xef721820  _decimal_to_double
      0xef75aba8  number
      0xef75a94c  __doscan_u
      0xef75ecf8  sscanf
      0x00010f20  main

このプログラムを別のシステムで再コンパイルまたは実行すると、上記テキストとは異な るアドレスが生成される可能性があります。

属性
次の属性については、 attributes(5) を参照してください。

属性タイプ | 属性値
使用条件 | SPROm9xs
インタフェース安定性 | 安定
MT レベル | MT-安全 (次を参照)

関連項目
feclearexcept(3M), fegetenv(3M), fex_set_handling(3M), ieee_retrospective(3M), attributes(5)

『 数値計算ガイド 』

注意事項
1 つのプロセス内のすべてのスレッドは同じログファイルを共有します。 fex_set_log() への各呼び出しは、以前の呼び出しよりも優先されます。

実行可能ファイルとそれが使用する任意の共有オブジェクトから記号名を取得するために 、ログファイルの作成中、ログファイル自身に加え、2 つの補助的なファイル記述子が使 用されます。これらのファイル記述子はログエントリが書き込まれると廃棄されます。こ れらのファイル記述子を割り当てられなかった場合、記号名はスタックトレースから省略 されます。

このページに記述されている関数は、必要に応じて自動的に、SIGFPE ハンドラを インストールまたはインストール解除し、浮動小数点状態レジスタのトラップ有効モード ビットを設定またはクリアします。これらの関数をプログラムで使用し、個別に、 SIGFPE ハンドラをインストールしようとした場合、あるいはトラップ有効モード ビットを制御しようとした場合、その結果の動作は定義されていません。

fex_set_handling(3M) に記述されているように、FEX_CUSTOM モードでイ ンストールされている処理関数が呼び出されると、すべての例外トラップは無効になり ます。そして、SIGFPE がブロックされている間は、再び有効になることはありません。 したがって、このようなハンドラ内で発生した例外に対して、遡及診断メッセージは記録 されません。

「形式」で示しているように、cc で libm9x とリンクするためには、コマンド行 で次のように指定することを推奨します。

    -Rinstall-path/lib -Linstall-path/lib -lm9x

install-path には、コンパイラがインストールされている場所を指定します (デ フォルトでは、/opt/SUNWspro)。libm9x とリンクする方法についての詳細は、 『数値計算ガイド』を参照してください。