Divide-by-zero error

Figure 1 demonstrates a divide-by-zero error. In this example, the main Fortran program passed 0 to subroutine DIVZEROSUB, and the error occurred when DIVZEROSUB attempted to use this data as a divisor.

Figure 1. Fortran routine with a divide-by-zero error
OPTIONS IN EFFECT: LIST NOMAP NOXREF NOGOSTMT NODECK SOURCE TERM OBJECT FIXED TRMFLG SRCFLG NODDIM NORENT SDUMP(ISN)
                   NOSXM NOVECTOR IL(DIM) NOTEST SC(*) NODC NOEC NOEMODE NOICA NODIRECTIVE NODBCS NOSAA NOPARALLEL NODYNAMIC NOSYM
                   NOREORDER NOPC
                   OPT(0) LANGLVL(77) NOFIPS FLAG(I) HALT(S) AUTODBL(NONE) PTRSIZE(8) LINECOUNT(60) CHARLEN(500) NAME(MAIN#)
           1         PROGRAM DIVZERO
           2         INTEGER*4 ANY_NUMBER
           3         INTEGER*4 ANY_ARRAY(3)
           4         PRINT *,'EXAMPLE STARTING'
           5         ANY_NUMBER = 0
           6         DO I = 1,3
     1     7         ANY_ARRAY(I) = I
     1     8         END DO
           9         CALL DIVZEROSUB(ANY_NUMBER, ANY_ARRAY)
          10         PRINT *,'EXAMPLE ENDING'
          11         STOP
          12         END
OPTIONS IN EFFECT: LIST NOMAP NOXREF NOGOSTMT NODECK SOURCE TERM OBJECT FIXED TRMFLG SRCFLG NODDIM NORENT SDUMP(ISN)
                   NOSXM NOVECTOR IL(DIM) NOTEST SC(*) NODC NOEC NOEMODE NOICA NODIRECTIVE NODBCS NOSAA NOPARALLEL NODYNAMIC NOSYM
                   NOREORDER NOPC
                   OPT(0) LANGLVL(77) NOFIPS FLAG(I) HALT(S) AUTODBL(NONE) PTRSIZE(8) LINECOUNT(60) CHARLEN(500) NAME(MAIN#)
           1         SUBROUTINE DIVZEROSUB(DIVISOR, DIVIDEND)
           2         INTEGER*4 DIVISOR
           3         INTEGER*4 DIVIDEND(3)
           4         PRINT *,'IN SUBROUTINE DIVZEROSUB'
           5         DIVIDEND(1) = DIVIDEND(3) / DIVISOR
           6         PRINT *,'END OF SUBROUTINE DIVZEROSUB'
           7         RETURN
           8         END

Figure 2 shows the Language Environment dump for routine DIVZERO.

Figure 2. Language Environment dump from divide-by-zero Fortran example
CEE3DMP V1 R3.0: Condition processing resulted in the unhandled condition.         08/30/01 10:33:01 AM                 Page:    1

Information for enclave DIVZERO

  Information for thread 8000000000000000

  Traceback:
    DSA Addr  Program Unit  PU Addr   PU Offset  Entry         E Addr    E  Offset   Statement  Load Mod  Service  Status
    0002D018  CEEHDSP       05936760  +0000277C  CEEHDSP       05936760  +0000277C              CEEPLPKA           Call
    05900640  DIVZSUB       05900558  +00000258  DIVZSUB       05900558  +00000258       5_ISN  GO                 Exception
    0002F018  AFHLCLNR      0001B150  +00000000  AFHLCLNR      0001B150  +00000000              AFHPRNBG           Call
    059002E8  DIVZERO       05900200  +00000298  DIVZERO       05900200  +00000298       9_ISN  GO                 Call

  Condition Information for Active Routines
    Condition Information for DIVZSUB   (DSA address 05900640)
      CIB Address: 0002D468
      Current Condition:
        CEE3209S The system detected a fixed-point divide exception.
      Location:
        Program Unit: DIVZSUB
        Entry:        DIVZSUB
        Statement:    5_ISN Offset: +00000258
      Machine State:
        ILC..... 0004    Interruption Code..... 0009
        PSW..... 078D2A00 859007B4
        GPR0..... 00000000  GPR1..... 00000003  GPR2..... 059003FC  GPR3..... 05900400
        GPR4..... 007F6930  GPR5..... 05900468  GPR6..... 0000000C  GPR7..... 059003E0
        GPR8..... 85900400  GPR9..... 807FD4F8  GPR10.... 00000000  GPR11.... 007FD238
        GPR12.... 00E21ED2  GPR13.... 05900640  GPR14.... 8590079C  GPR15.... 05900BA0
    Storage dump near condition, beginning at location: 059007A0
      +000000 059007A0  5870D118 5800700C 5870D120 8E000020  5D007000 5870D118 50107004 58F0D128  |..J.......J.....).....J.&....0J.|

  Parameters, Registers, and Variables for Active Routines:
    CEEHDSP (DSA address 0002D018):
      Saved Registers:
        GPR0..... 00000000  GPR1..... 0002D3B4  GPR2..... 0002DFD7  GPR3..... 0002E027
        GPR4..... 0002DF94  GPR5..... 00000000  GPR6..... 00000004  GPR7..... 00000000
        GPR8..... 0002E017  GPR9..... 0593875E  GPR10.... 0593775F  GPR11.... 05936760
        GPR12.... 00014770  GPR13.... 0002D018  GPR14.... 800250DE  GPR15.... 85949C70

  GPREG STORAGE:
    Storage around GPR0 (00000000)
      +000000 00000000  Inaccessible storage.
      +000020 00000020  Inaccessible storage.
      +000040 00000040  Inaccessible storage.
    Storage around GPR1 (0002D3B4)
      -000020 0002D394  00000006 00000000 0002E017 0593875E  0593775F 05936760 00014770 00000000  |.............lg;.l.¬.l.-........|
      +000000 0002D3B4  0002DFD7 0002E027 0002DF94 0002DF94  0002DDF4 0002DEC4 0002E158 00000000  |...P.......m...m...4...D........|
      +000020 0002D3D4  0002D468 00000000 00000000 00000007  859D67E0 00000000 00000000 05914848  |..M.............e............j..|
   ⋮
      Local Variables:
          I                INTEGER*4                  4

          ANY_ARRAY(3)     INTEGER*4
          ANY_ARRAY(1)                                1           2           3

          ANY_NUMBER       INTEGER*4                  0

  File Status and Attributes:
    The total number of units defined is 100.
    The default unit for the PUNCH statement is 7.
    The default unit for the Fortran error messages is 6.
    The default unit for formatted sequential output is 6.
    The default unit for formatted sequential input is 5.

To debug this application, do the following:

  1. Locate the error message, CEE3209S, for the current condition in the Condition Information section of the dump, shown in Figure 2. The system detected a fixed-point divide exception. See z/OS Language Environment Runtime Messages for additional information about this message.
  2. Note the sequence of the calls in the call chain:
    1. DIVZERO called AFHLCLNR, which is a Fortran library subroutine.
    2. AFHLCLNR called DIVZEROSUB.
      Note: When a program-unit name is longer than 7 characters, the name as it appears in the dump consists of the first 4 and last 3 characters concatenated together.
    3. DIVZEROSUB attempted a divide-by-zero operation at statement 5.
    4. This resulted in a call to CEEHDSP, a Language Environment condition handling routine.
  3. Locate statement 5 in the Fortran listing for the DIVZEROSUB subroutine in Figure 2. This is an instruction to divide the contents of DIVIDEND(3) by DIVISOR.
  4. Since DIVISOR is a parameter of subroutine DIVZEROSUB, go to the Parameters section of the dump shown in Figure 2. The parameter DIVISOR shows a value of 0.
  5. Since DIVISOR contains the value passed to DIVZEROSUB, check its value. ANY_NUMBER is the actual argument passed to DIVZEROSUB, and the dump and listing of DIVZERO indicate that ANY_NUMBER had value 0 when passed to DIVZEROSUB, leading to the divide-by-zero exception.