Obtaining Traceback Information with TRACEBACKQQ

You can obtain traceback information in your application by calling the TRACEBACKQQ routine.

TRACEBACKQQ allows an application to initiate a stack trace. You can use this routine to report application detected errors, use it for debugging, and so on. It uses the standard stack trace support in the Visual Fortran run-time system to produce the same output that the run-time system produces for unhandled errors and exceptions (severe error message). The TRACEBACKQQ subroutine generates a stack trace showing the program call stack as it was leading up to the point of the call to TRACEBACKQQ.

The error message string normally included from the run-time support is replaced with the user-supplied message text or omitted if no user string is specified. Traceback output is directed to the target destination appropriate for the application type, just as it is when traceback is initiated internally by the run-time support. See the sections Using Traceback Information and Run-Time Message Display and Format for more information.

In the most simple case, a user can generate a stack trace by coding the call to TRACEBACKQQ with no arguments:

  CALL TRACEBACKQQ()

This call causes the run-time library to generate a traceback report with no leading header message, from wherever the call site is, and terminate execution.

You can specify arguments that generate a stack trace with the user-supplied string as the header and instead of terminating execution, return control to the caller to continue execution of the application. For example:

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

By specifying a user exit code of -1, control returns to the calling program. Specifying a user exit code with a positive value requests that specified value be returned to the operating system. The default value is 0, which causes the application to abort execution.

The following example demonstrates the use of the EPTR argument when calling from a user defined exception filter function. The premise of the example is a Fortran DLL containing entry points protected by a C try/except construct, such as:

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

The C function shown above is guarding against a floating-point divide-by-zero exception. This function calls the user-supplied FPE_TEST (not shown). The Fortran function CHECK_EXCEPTION_INFO shown below (called in the __except filter expression above) can use TRACEBACKQQ to get a stack trace as follows:

   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

! Init the arguments to TRACEBACKQQ appropriately for your needs...

   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

To return a pointer to C run-time exception information pointers within a user-defined handler that was established with SIGNALQQ (or directly with the C signal function), you can call the GETEXCEPTIONPTRSQQ routine.

For an example of how to establish a signal handler with SIGNALQQ (or the C signal() function) and use the TRACEBACKQQ and GETEXCEPTIONPTRSQQ routines to generate a traceback display from the handler, see the Visual Fortran Sample GetEptrs (in ...\Df98\Samples\ExceptionHandling\GetEptrs).