TRACEBACKQQ を使ったトレースバック情報の入手

TRACEBACKQQ ルーチンを使うと,トレースバック情報がアプリケーションで入手することができます。

アプリケーションは,TRACEBACKQQ でスタック・トレースを初期化することができます。このルーチンを検出したエラーをアプリケーションに通知するために使用したり,デバッグに利用したりすることなどができます。Visual Fortran 実行時ライブラリーがサポートする標準スタック・トレースを,実行時ライブラリーが未処理エラーや例外 (重大エラー・メッセージ) で生成するのと同じ出力を生成するために使用します。TRACEBACKQQ サブルーチンは,TRACEBACKQQ の呼び出し点に到達したときのプログラム・コール・スタックを表示するスタック・トレースを生成します。

実行時サポートからのエラー・メッセージは,ユーザー提供のメッセージで置き換えられるか,ユーザーがメッセージを提供しなければ省略されます。トレースバック出力は,トレースバックが実行時サポートによって内部的に初期化されたときのアプリケーション形式に合った出力先に送られます。詳細は,「トレースバック情報の使用」と「実行時メッセージの表示と書式」を参照してください。

多くの単純な場合では,ユーザーは,引数なしで TRACEBACKQQ を呼び出すコーディングでスタック・トレースを生成することができます。

	CALL TRACEBACKQQ()

この呼び出しは,呼び出し場所がどこであっても,実行時ライブラリーにトレースバック報告を最初のヘッダ情報なしで生成させ,実行を終了させます。

ユーザー指定文字をヘッダとしたスタック・トレースを生成し,実行を終了させる代わりに,アプリケーションの実行を継続すために呼び出し側に制御を戻す引数を指定することができます。以下に例を示します。

	CALL TRACEBACKQQ(STRING="Done with pass 1",USER_EXIT_CODE=-1)

ユーザー終了コードに -1 を指定することで,制御が呼び出し側プログラムに返ります。正の値をユーザー終了コードに指定すると,指定した値をオペレーティング・システムに返すことを要求したことになります。基本値は 0 で,アプリケーションが実行を止めることになります。

以下の例は,ユーザー定義例外フィルタ関数からの呼び出しでの FPTR 引数の使用方法を示しています。この例の前提は,次のような C Try/Except 構文で保護されたエントリ・ポイントを含む Fortran DLL です。

	__declspec(dllexport) void FPE_TEST_WRAPPER ()
	{
	__try {
	      /*
	      **  call the Fortran code...
	      */
	      FPE_TEST() ;
	      }
	__except ( CHECK_EXCEPTION_INFO ( GetExceptionInformation() ) )
	      {
	      /*
	      **  noncontinuable exception handling here, if any.
	      */
	      }

上述の C 関数は,浮動小数点の divide-by-zero 例外に対する保護を行っています。この関数は,ユーザー提供の FPE_TEST (例示していません) を呼び出しています。以下に示す Fortran 関数 CHECK_EXCEPTION_INFO (上記 __except フィルタ式で呼び出されています) は,以下のようにスタック・トレースを入手するために TRACEBACKQQ を使っています。

	 INTEGER*4 FUNCTION CHECK_EXCEPTION_INFO ( ExceptionInfo )
	!DEC$ ATTRIBUTES DLLEXPORT::CHECK_EXCEPTION_INFO
	 USE DFWINTY
	!DEC$ ATTRIBUTES REFERENCE :: ExceptionInfo
	 TYPE(T_EXCEPTION_POINTERS) ExceptionInfo
	 TYPE(T_EXCEPTION_RECORD) erecptr
	 TYPE(T_CONTEXT) ctxptr
	 POINTER(eptr,erecptr)
	 POINTER(ctxp,ctxptr)
	 INTEGER(4) EXIT_CODE,STS
	 CHARACTER(LEN=70) MYSTR
	! 必要に応じて適当に TRACEBACKQQ の引数を初期化します。
	 EXIT_CODE=-1
	 eptr = ExceptionInfo.ExceptionRecord
	 ctxp = ExceptionInfo.ContextRecord
	 IF ( erecptr.ExceptionCode .EQ. STATUS_FLOAT_DIVIDE_BY_ZERO ) THEN
	   PRINT *, 'Saw floating divide by zero.'
	   PRINT '(1x,a,z8.8)', 'ContextRecord.FloatSave.StatusWord = ', &
	         ctxptr.FloatSave.StatusWord
	   MYSTR = "FLTDIV EXCEPTION IN MY APPLICATION"
	   CALL TRACEBACKQQ(MYSTR,EXIT_CODE,STS, %LOC(ExceptionInfo))
	 END IF
	 .
	 .
	 .
	 CHECK_EXCEPTION_INFO = 1
	 END

SIGNALQQ (または C シグナル関数を直接呼び出すこと) で確立したユーザー定義ハンドラ内で C 実行時例外情報ポインタへのポインタを返すには,GETEXCEPTIONPTRSQQ ルーチンを呼び出します。

SIGNALQQ (または C signal() 関数) でシグナル・ハンドラを確立方法の例とハンドラからトレーバック表示を生成するための TRACEBACKQQ および GETEXCEPTIONPTRSQQ ルーチンの使用方法の例については,Visual Fortran サンプルGetEptrs (...\Df98\Samples\ExceptionHandling\GetEptrs ディレクトリ) を参照してください。