# Sample Programs and Traceback Information

The following sections provide sample programs that show the use of traceback to locate the cause of the error:

- Example: End-of-File Condition, Program teof

- Example: Machine Exception Condition, Program ovf

Note that the hex PC's and contents of registers displayed in these program outputs are meant as representative examples of typical output. The PC's will change over time, as the libraries and other tools used to create an image change.

## Example: End-of-File Condition, Program teof

In the following example, a READ statement creates an End-Of-File error, which the application has not handled:

      program teof
      integer*4 i,res
      i=here( )
      end
     integer*4 function here( )
      here = we( )
      end
     integer*4 function we( )
      we = go( )
      end
     integer*4 function go( )
      go = again( )
      end
     integer*4 function again( )
      integer*4 a
      open(10,file='xxx.dat',form='unformatted',status='unknown')
      read(10) a
      again=a
      end

The diagnostic output that results when this program is built with traceback enabled, optimization disabled, and linked against the shared Fortran run-time library on the Intel® 64 architecture platform is similar to the following:

    forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
    Image            PC                Routine               Line     Source
    libifcorert.dll  000007FED2B232D9  Unknown               Unknown  Unknown
    libifcorert.dll  000007FED2B6CEE0  Unknown               Unknown  Unknown
    teof.exe         000000013F931193  AGAIN                      17  teof.f90
    teof.exe         000000013F93109B  GO                         12  teof.f90
    teof.exe         000000013F931072  WE                          9  teof.f90
    teof.exe         000000013F931049  HERE                        6  teof.f90
    teof.exe         000000013F93101E  MAIN__                      3  teof.f90
    teof.exe         000000013F96ADCE  Unknown               Unknown  Unknown
    teof.exe         000000013F96B64C  Unknown               Unknown  Unknown
    kernel32.dll     0000000076CC59BD  Unknown               Unknown  Unknown
    ntdll.dll        0000000076EFA2E1  Unknown               Unknown  Unknown

If optimization is not disabled (/Od on Windows* or -O0 on Linux* and macOS), procedure inlining may collapse the call stack and make it more difficult to locate a problem.

The first line of the output is the standard Fortran run-time error message. What follows is the result of walking the call stack in reverse order to determine where the error originated. Each line of output represents a call frame on the stack. Since the application was compiled with the traceback option, the PCs that fall in Fortran code are correlated to their matching routine name, line number and source module. PCs that are not in Fortran code are not correlated and are reported as "Unknown."

The first two frames show the calls to routines in the Fortran run-time library (in reverse order). Since the application was linked against the shared version of the library, the image name reported is either libifcore.so (Linux* and macOS) or libifcorert.dll (Windows*). These are the run-time routines that were called to do the READ and upon detection of the EOF condition, were invoked to report the error. In the case of an unhandled I/O programming error, there will always be a few frames on the call stack down in run-time code like this.

The stack frame of real interest to the Fortran developer is the first frame in image teof.exe, which shows that the error originated in the routine named AGAIN in source module teof.f90 at line 17. Looking in the source code at line 21, you can see the Fortran READ statement that incurred the end-of-file condition.

The next four frames show the trail of calls in the Fortran user code that led to the routine that got the error (TEOF->HERE->WE->GO->AGAIN).

Finally, the bottom four frames are routines which handled the startup and initialization of the program.

If this program had been linked against the static Fortran run-time library, the output would then look like:

    forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
    Image            PC                Routine               Line     Source
    teof.exe         000000013F941FFB  Unknown               Unknown  Unknown
    teof.exe         000000013F9380A0  Unknown               Unknown  Unknown
    teof.exe         000000013F931193  AGAIN                      17  teof.f90
    teof.exe         000000013F93109B  GO                         12  teof.f90
    teof.exe         000000013F931072  WE                          9  teof.f90
    teof.exe         000000013F931049  HERE                        6  teof.f90
    teof.exe         000000013F93101E  MAIN__                      3  teof.f90
    teof.exe         000000013F96ADCE  Unknown               Unknown  Unknown
    teof.exe         000000013F96B64C  Unknown               Unknown  Unknown
    kernel32.dll     0000000076CC59BD  Unknown               Unknown  Unknown
    ntdll.dll        0000000076EFA2E1  Unknown               Unknown  Unknown

Notice that the initial two stack frames now show routines in image teof.exe, not libifcore.so (Linux and macOS) or libifcorert.dll (Windows). The routines are the same two run-time routines as previously reported for the shared library case but since the application was linked against the archive library libifcore.a (Linux and macOS) or the static Fortran run-time library libifcore.lib (Windows), the object modules containing these routines were linked into the application image (teof.exe). You can use a Generating Listing and Map Files to determine the locations of uncorrelated PCs.

Now suppose the application was compiled without traceback enabled and, once again, linked against the static Fortran library. The diagnostic output would appear as follows:

    forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
    Image            PC                Routine               Line     Source
    teof.exe         000000013F851FFB  Unknown               Unknown  Unknown
    teof.exe         000000013F8480A0  Unknown               Unknown  Unknown
    teof.exe         000000013F841193  Unknown               Unknown  Unknown
    teof.exe         000000013F84109B  Unknown               Unknown  Unknown
    teof.exe         000000013F841072  Unknown               Unknown  Unknown
    teof.exe         000000013F841049  Unknown               Unknown  Unknown
    teof.exe         000000013F84101E  Unknown               Unknown  Unknown
    teof.exe         000000013F87ADCE  Unknown               Unknown  Unknown
    teof.exe         000000013F87B64C  Unknown               Unknown  Unknown
    kernel32.dll     0000000076CC59BD  Unknown               Unknown  Unknown
    ntdll.dll        0000000076EFA2E1  Unknown               Unknown  Unknown

Without the correlation information in the image that option traceback previously supplied, the Fortran run-time system cannot correlate PC's to routine name, line number, and source file. You can still use the Generating Listing and Map Files to at least determine the routine names and what modules they are in.

Remember that compiling with the traceback option increases the size of your application's image because of the extra PC correlation information included in the image. You can see if the extra traceback information is included in an image (checking for the presence of a .trace section) by entering:

    objdump -h your_app.exe   ! Linux OS
    otool -l your_app.exe     ! macOS
    link -dump -summary your_app.exe   ! Windows OS

Build your application with and without traceback and compare the file size of each image. Check the file size with a simple directory command.

For this simple teof.exe example, the traceback correlation information adds about 512 bytes to the image size. In a real application, this would probably be much larger. For any application, the developer must decide if the increase in image size is worth the benefit of automatic PC correlation or if manually correlating PC's with a map file is acceptable.

If an error occurs when traceback was requested during compilation, the run-time library will produce the correlated call stack display.

If an error occurs when traceback was disabled during compilation, the run-time library will produce the uncorrelated call stack display.

If you do not want to see the call stack information displayed, you can set the Supported Environment Variable FOR_DISABLE_STACK_TRACE to true. You will still get the Fortran run-time error message:

    forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat

## Example: Machine Exception Condition, Program ovf

The following program generates a floating-point overflow exception when compiled with the fpe option value 0:

      program ovf
      real*4 a
      a=1e37
      do i=1,10
        a=hey(a)
      end do
      print *, 'a= ', a
      end
     real*4 function hey(b)
      real*4 b
      hey = watch(b)
      end
     real*4 function watch(b)
      real*4 b
      watch = out(b)
      end
     real*4 function out(b)
      real*4 b
      out = below(b)
      end
     real*4 function below(b)
      real*4 b
      below = b*10.0e0
      end

Assume this program is compiled with the following:

- Option fpe value 0

- Option traceback

- Option -O0 (Linux and macOS) or /Od (Windows)

On a system based on IA-32 architecture, the traceback output is similar to the following:

    forrtl: error (72): floating overflow
    Image              PC        Routine               Line     Source
    ovf.exe            001211A3  _BELOW                     23  ovf.f90
    ovf.exe            0012116F  _OUT                       19  ovf.f90
    ovf.exe            0012113D  _WATCH                     15  ovf.f90
    ovf.exe            0012110B  _HEY                       11  ovf.f90
    ovf.exe            0012104E  _MAIN__                     5  ovf.f90
    ovf.exe            0015B31F  Unknown               Unknown  Unknown
    ovf.exe            0015BADD  Unknown               Unknown  Unknown
    kernel32.dll       7515338A  Unknown               Unknown  Unknown
    ntdll.dll          770E9902  Unknown               Unknown  Unknown
    ntdll.dll          770E98D5  Unknown               Unknown  Unknown

Notice that unlike the previous example of an unhandled I/O programming error, the stack walk can begin right at the point of the exception. There are no run-time routines on the call stack to dig through. The overflow occurs in routine BELOW at PC 001211A3, which is correlated to line 23 of the source file ovf.f90.

When the program is compiled at a higher optimization level of O2, along with option fpe value 0 and the traceback option, the traceback output appears as follows:

    forrtl: error (72): floating overflow
    Image              PC        Routine               Line     Source
    ovf.exe            00AE1059  _MAIN__                     7  ovf.f90
    ovf.exe            00B1B75F  Unknown               Unknown  Unknown
    ovf.exe            00B1BADD  Unknown               Unknown  Unknown
    kernel32.dll       7515338A  Unknown               Unknown  Unknown
    ntdll.dll          770E9902  Unknown               Unknown  Unknown
    ntdll.dll          770E98D5  Unknown               Unknown  Unknown

With O2, the entire program has been inlined.

The main program, OVF, no longer calls routine HEY. While the output is not quite what one might have expected intuitively, it is still entirely correct. You need to keep in mind the effects of compiler optimization when you interpret the diagnostic information reported for a failure in a release image.

If the same image were executed again, this time with the environment variable called TBK_ENABLE_VERBOSE_STACK_TRACE set to True, you would also see a dump of the exception context record at the time of the error. Here is an excerpt of how that might appear on a system using IA-32 architecture:

    forrtl: error (72): floating overflow
    Hex Dump Of Exception Record Context Information:
    Exception Context:  Processor Control and Status Registers.
    EFlags:  00010212
    CS:  0000001B  EIP:  00401161  SS:   00000023  ESP:  0012FE38  EBP:  0012FE60
    Exception Context:  Processor Integer Registers.
    EAX: 00444488  EBX:  00000009  ECX:  00444488  EDX:  00000002
    ESI: 0012FBBC  EDI:  F9A70030
    Exception Context:  Processor Segment Registers.
    DS:  00000023  ES:   00000023  FS:   00000038  GS:   00000000
    Exception Context:  Floating Point Control and Status Registers.
    ControlWord:  FFFF0262  ErrorOffset:    0040115E  DataOffset:    0012FE5C
    StatusWord:   FFFFF8A8  ErrorSelector:  015D001B  DataSelector:  FFFF0023
    TagWord:      FFFF3FFF  Cr0NpxState:    00000000
    Exception Context:  Floating Point RegisterArea.
    RegisterArea[00]:  4080BC143F4000000000  RegisterArea[10]:  F7A0FFFFFFFF77F9D860
    RegisterArea[20]:  00131EF0000800060012  RegisterArea[30]:  00000012F7C002080006
    RegisterArea[40]:  02080006000000000000  RegisterArea[50]:  0000000000000012F7D0
    RegisterArea[60]:  00000000000000300000  RegisterArea[70]:  FBBC000000300137D9EF
    ...

Parent topic: Traceback

## See Also

traceback compiler option
fpe compiler option
O compiler option
Od compiler option