gtpa2m42Application Programming

Run-Time Debugging

Errors that occur while running a program can be vastly more difficult to correct than syntactic errors. This section contains some topics that will help.

Function Mismatches

This is one type of error to check when you are having a problem.

Description

When a program calls a function, the stub associated with the function provides an index into the AOLA and an index into the corresponding library vector. Online this identifies the executable code for the function. If either of these indexes do not match the online system, unexpected function calls can result.

There are several places where this can go wrong.

Refer to the IDSLST DSECT for the structure of the AOLA.

Indications

To determine whether this problem exists compare the name of the function being called with the name of the code being executed.

The name of the function code being executed is found at the beginning of the executable code identified by the LIBVEC. Refer to the library build script for the library name and LIBVEC index for the function. Assume for the following example the function is FUNC in library CTAL.

The library ordinal number for a given library can be displayed online by doing the following:

  1. Lock the library load module into main memory using ZRPGM. The address returned is the starting address of the loadset.
    +--------------------------------------------------------------------------------+
    | ZRPGM CTAL LOCK                                                                |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | RPGM0001I 19.56.44 PROGRAM CTAL LOADSET BASE LOCKED IN CORE                    |
    | ------------------ AT ADDRESS 00820BB0                                         |
    |                                                                                |
    +--------------------------------------------------------------------------------+
  2. Display the loadset entry for the library load module using ZDCOR. This provides the library name and address of its library vector.
    +--------------------------------------------------------------------------------+
    | ZDCOR 820BB0.10                                                                |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | DCOR0010I 19.56.44 BEGIN DISPLAY                                               |
    |  00820BB0- 0000FFFF C3E3C1D3 00822D28 00000000 ....CTAL ........               |
    | END OF DISPLAY - ZEROED LINES NOT DISPLAYED                                    |
    +--------------------------------------------------------------------------------+

  3. Using ZDCOR display main storage at the address shown by the previous step. The value 00000001 is the ordinal number of CTAL.

    +--------------------------------------------------------------------------------+
    | ZDCOR 822D28.10                                                                |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | DCOR0010I 19.56.44 BEGIN DISPLAY                                               |
    |  00822D28- 00000001 00820BB0 00823E60 00823EB8 ........ ........               |
    | END OF DISPLAY - ZEROED LINES NOT DISPLAYED                                    |
    +--------------------------------------------------------------------------------+
  4. Using ZDCOR display main storage at the function address displayed by the previous step. Assume the function has LIBVEC ordinal 2. This puts it at 00823EB8.
    +--------------------------------------------------------------------------------+
    | ZDCOR 823EB8.10                                                                |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | DCOR0010I 19.56.44 BEGIN DISPLAY                                               |
    |  00823EB8- 4700C004 C6E4D5C3 18781894 5850C006 ....FUNC ........               |
    | END OF DISPLAY - ZEROED LINES NOT DISPLAYED                                    |
    +--------------------------------------------------------------------------------+

Identifying the Library Ordinal Number

A library ordinal number can be found using the shared library names table (SLNT).

Description

As the library addresses are filled into the AOLA structure, the 4-character name of the library load module is filled into the SLNT. The library ordinal number is used to place the library name into the SLNT.

Indications

The SLNT is located in the CCISOC CSECT and can be displayed online by doing the following:

  1. Display the address of the CP link map using ZDDCA LMP
    +--------------------------------------------------------------------------------+
    | ZDDCA LMP                                                                      |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | DDCA0001I 19.56.44 DUMP TAG LMP  ADDRESS - 000B9BB0                            |
    +--------------------------------------------------------------------------------+
  2. Display the CP link map using ZDCOR and find the address of CCISOC.
    +--------------------------------------------------------------------------------+
    | ZDCOR B9BB0.40                                                                 |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | DCOR0010I 19.56.44 BEGIN DISPLAY                                               |
    |  000B9BB0- C3C3D3C9 C4C8F4F0 000BB000 00000500 CCLIDH40 ........               |
    |  000B9BC0- C3C3C9E2 D6C3F4F0 000BC000 00003850 CCISOC40 ........               |
    |  000B9BD0- C3C3D3C1 D5C7F4F0 000C0000 00009500 CCLANG40 ........               |
    |  000B9BE0- C3C3D4E3 C8F1F4F0 000C9500 00000002 CCMTH140 ........               |
    | END OF DISPLAY - ZEROED LINES NOT DISPLAYED                                    |
    +--------------------------------------------------------------------------------+
  3. Display CCISOC using ZDCOR. The SLNT is located at the beginning of CCISOC. Libraries CISO and CTAL are ordinal numbers 0 and 1.
    +--------------------------------------------------------------------------------+
    | ZDCOR BC000.100                                                                |
    | CSMP0097I 19.56.44 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | DCOR0010I 19.56.44 BEGIN DISPLAY                                               |
    |  000BC000- 000BF034 000BC01C 000BD024 00000000 ..0..... ........               |
    |  000BC010- 00000000 E2D3D5E3 00000000 C3C9E2D6 ....SLNT ....CISO               |
    |  000BC020- C3E3C1D3 40404040 40404040 40404040 CTAL                            |
    |  000BC030- D8D7D5F0 40404040 40404040 40404040 QPN0                            |
    |  000BC040- 40404040 40404040 40404040 40404040                                 |
    |     
    ·
    ·
    ·
    | | 000BC0E0- 40404040 40404040 40404040 40404040 | | 000BC0F0- 40404040 40404040 40404040 40404040 | | END OF DISPLAY - ZEROED LINES NOT DISPLAYED | +--------------------------------------------------------------------------------+

ISO-C Dynamic Load Modules (DLMs)

The TPF DLM startup code (CSTRTD) provides a bridge between TPF Enter/Back services and the ISO-C environment. Because CSTRTD receives control whenever an ISO-C DLM is called, CSTRTD must be defined as the first object in the load module. The entry point function will be called from within CSTRTD and, when the function ends, control returns to CSTRTD. Because the entry point is resolved in the TPF startup code, the prelinker and linkage editor list the following message:

IEW2650I 5102 MODULE ENTRY NOT PROVIDED.  ENTRY DEFAULTS TO SECTION CSTRTD

CSTRTD obtains the address of the entry point function through the weak external @@DLMENT. @@DLMENT is resolved by the loader to the address of the function with a name equivalent to the name of the load module.

For example, load module DLM1 has an entry point function named DLM1. If there is no function called DLM1, the TPF offline loader returns with a condition code 8 and lists the following reason:

DLM ENTRY PT NOT FOUND IN MODULE.

Stub routines are used to resolve the VCONs produced by the compiler for library function calls and external function calls, which can reside in BAL segments, TARGET(TPF) segments, or other ISO-C segments. It is important to inspect the output of the prelinker to verify the correct stubs are merged into the load module.

@@DLMENT is used to get the address of the DLM prolog entry point. The address of @@DLMENT itself comes from the link map generated during linkage editing.

To display online the address of @@DLMENT, do the following:

  1. Lock the C load module into main storage using the ZRPGM command with the LOCK parameter:
    +--------------------------------------------------------------------------------+
    | ZRPGM CIM9 LOCK                                                                |
    | CSMP0097I 15.45.12 CPU-B SS-BSS  SSU-HPN  IS-01                                |
    | RPGM0001I 15.45.12 PROGRAM CIM9 LOADSET BASE LOCKED IN CORE                    |
    | ------------------ AT ADDRESS 01F91690                                         |
    +--------------------------------------------------------------------------------+
  2. Use the ZDCOR command with the address shown in the previous step. @@DLMENT is at offset X'14' from this address. In the following example, the DLM entry point is at address X'1F91700'.
    +--------------------------------------------------------------------------------+
    |ZDCOR 1F91690.20                                                                |
    |CSMP0097I 15.45.12 CPU-B SS-BSS  SSU-HPN  IS-01                                 |
    |DCOR0010I 15.45.12 BEGIN DISPLAY                                                |
    | 01F91690- 0000FFFF C3C9D4F9 00000000 01F91988 ....CIM9 .....9..                |
    | 01F916A0- 00000000 01F91700 00000000 00000000 .....9.. ........                |
    |END OF DISPLAY - ZEROED LINES NOT DISPLAYED                                     |
    +--------------------------------------------------------------------------------+

The following example of the file map shows the two object files specified in the prelink job and all the stub routines automatically included by the prelinker.

========================================================================
|                               File Map                               |
========================================================================
 
*ORIGIN  FILE ID  FILE NAME
 
   PI     00001   DD:OBJLIB(CSTRTDNA)
   PI     00002   DD:OBJLIB(CIMANC)
   A      00003   ISO0000.DEVP.STUB.OB(@CINIT)
   A      00004   ISO0000.DEVP.STUB.OB(STRPBRK)
   A      00005   ISO0000.DEVP.STUB.OB(CRFA)
   A      00006   ISO0000.DEVP.STUB.OB(EXIT)
   A      00007   ISO0000.DEVP.STUB.OB(CIMZ)
   A      00008   ISO0000.DEVP.STUB.OB(ATOI)
   A      00009   ISO0000.DEVP.STUB.OB(CIMC)
   A      00010   ISO0000.DEVP.STUB.OB(CIMB)
 
*ORIGIN:  P=primary input     PI=primary INCLUDE    SI=secondary INCLUDE
          A=automatic call     R=RENAME card         L=C Library

Storage for ISO-C Static Variables

If the compiler determines that 1 or more static variables are declared in a given source file, the object file needs to be processed by the prelinker. The linkage editor returns a condition code 8 and lists

@@XINIT@ as an UNRESOLVED EXTERNAL REFERENCE

for object files that contain static data but have not been processed by the prelinker. @@XINIT@ is defined to be the address of the static data length and is filled in by the prelinker.

Every time an ECB enters a DLM or a library that contains static, the startup code tests @@XINIT@ to see if there is an associated static area. If the load module contains static data, @@XINIT@ contains the address of the static data length; otherwise, it contains zero. The static data pointer in the TCA is saved in the startup code's stack frame. The static exception routine is called to find the current load module's static data area. The pointer that is returned by the static exception routine is saved in the TCA.

After the entry point function ends, the startup code restores the saved static data pointer to the TCA before returning to the control program.

ISO-C static frames are mapped by the IDSCSF data macro.

Layout of ISO-C Structures in a Dump

System error processing formats the contents of the ISO-C control structures, the ISO-C language support stack, and all static areas if the ISO-C environment exists.

The ISO-C TCA appears in the dump following the program area. The dump tags identify the following:

TCA
Beginning of the TCA structure

BOS
Address of the beginning of the ISO-C stack

EOS
Address of the end of the ISO-C stack

WSP
Address of the current writable static area

EPT
Address of the entry point function

CID
Beginning of the CID structure

WSC
Beginning of the writable static control block (WSCB)

CTC
Beginning of the CTCA structure

TPS
Beginning of the TPSA structure.

Figure 46. ISO-C Control Area Dump

 *ISOC CONTROL AREA
 
 01000010  TCA 00000000 00000000       BOS 01001964 01009FFF EOS       00000000 00000000           00000000 00000000
 01000030      00000000 00000000           00000000 00000000           0100A08C 0071C930           01009FFC 80A17E04
 01000050      0071C930 0700C198           01000200 00000000           00A17AB0 00300000           800F35CA 01002FFF
 01000070      01000010 01009F6C           00A17DF0 000BF7C0           00000000 000BF7C0           00000000 98000000
 01000090      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01000130      00000000 00000000           00000000 00000000           00000000 00000090           01000010 00002FF0
 01000150      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 010001B0      00000000 00000000           0700C198 0700C198           0700C198 0700C198           0700C198 0700C198
 010001D0      0700C198 0700C198           0700C198 0700C198           0700C198 0700C198           0700C198 0700C198
 010001F0      0700C198 0700C198           0700C198 0700C198           01000A64 00000000 WSP       4E000000 00000000
 01000210  PRM 00000000 00A17C7C           00030B02 010011F4           000BD024 01001544       EPT 00000000 00000004
 01000230      00000000 00000000           00000000 00000000           00000000 00000000           01000250 00000000
 01000250  CID 000BF7C0 000BF584           000F32C8 000F36A8           01000264 00000000 WSC       00000000 00000000
 01000270      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01000A50      00000000 00000000           00000000 00000000           00000000 00000620 CTC       00000000 00000000
 01000A70      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01000B70      00000000 0084134E           00004650 00842240           00841E48 00841F00           00841EB0 00841F88
 01000B90      00841F68 00842178           00842088 0084F040           00842198 00000000           00000000 00000000
 01000BB0      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01000C50      00000000 00000000           00000000 00000000           0000E2E8 E2C9D540           404000E2 E8E2D7D9
                        .
                        .
                        .
                        .
 010018D0      00000000 00000000 TPS       00000000 00000000           00000000 00000000           00000000 00000000
 01001950      00000000 00000000           00000000 00000000           00000000
 

The data in the ISO-C stack is broken down into the individual stack frames and each is tagged with the name of the function that created it.

The initial stack frame will always be the stack frame associated with TPF startup code CSTRTD when the ISO-C environment was initialized for this ECB. All stack frames point to the next structure, which is the LWS.

Figure 47. ISO-C Initial Stack Frame Dump

 *ISOC INITIAL STACK FRAME
 
 01001964      00000000 00000000 BKP       00000000 80A17C34 R14       00A17D08 01001CB4           0071C930 01000264
    BCD                                                  @                  '                           I
 01001984      01000250 0071C930           0700C198 01000200           00000000 00A17AB0           00300000 800F35CA
    BCD               &      I                  A
 010019A4      01002FFF 00000000 R12       01001A2C 01001B3C NAB       00000000 00000000           00000000 00000000
 010019C4      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 010019E4      00000000 0071C930           0071C496 00000038           00319E80 00319E80           00331560 003314B0
    BCD                      I                  D                                                         -
 01001A04      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01001A24      00000000 00000000
 
 
 *ISOC LWS
 
 01001A2C      0A320070 58D09250           58E0D00C 982CD01C           0D1E0082 DF180000           00000000 00000000
 01001A4C      00000000 00000000           00000000 00000000           01001B3C 00000000           00000000 00000000
 01001A6C      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01001B2C      00000000 00000000           00000000 00000000
 

The remaining stack frames are formatted in reverse order. The first function called will be at the bottom and the last function called will be at the top. Each stack frame is labeled with the #pragma map name of the function.

Each stack frame contains a register save area. While reviewing the register contents, keep in mind that the compiler saves only those registers which are used by the function.

Figure 48. ISO-C Stack Frame Function Dump

 *ISOC STACK FRAME FUNCTION-called_function
 
 01009F6C      10000000 01009EDC BKP       00000000 80A17E0A R14       00A17DB0 01009FFC           0071C930 01009F6C
    BCD                                                  =                  '                           I
 01009F8C      80A17E04 00000000           00000000 00000000           00000000 00000000           00000000 00000000
    BCD             =
 01009FAC      00000000 00000000 R12       01001A2C 01009FFC NAB       00000000 00000000           00000000 00000000
 01009FCC      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01009FEC      00000000 00000000           00000000 00000000
 
    .
    .
    .
 
 *ISOC STACK FRAME FUNCTION-called_function
 
 01001BCC      10000A64 01001B3C BKP       10000000 80A17E0A R14       00A17DB0 01001C5C           0071C930 01001BCC
    BCD                                                  =                  '          *                I
 01001BEC      80A17E04 000001F4           8087EA6A 00000070           00000000 00000000           01001CAC 00004650
    BCD             =          4                                                                                   &
 01001C0C      000004B0 00000000 R12       01001A2C 01001C5C NAB       01001A2C 01001CB4           00000000 00000000
    BCD                                                    *
 01001C2C      00000000 00000000           00000000 00000000           00000000 00000000           00000000 00000000
 01001C4C      00000000 00000000           00000000 00000000
 
 
 *ISOC STACK FRAME FUNCTION-qhph_first_function
 
 01001B3C      10000000 01001964 BKP       00000000 80A17D70 R14       00A17DB0 01001BCC           0071C930 01001B3C
    BCD                                                  '                  '                           I
 01001B5C      80A17D6A 0083E700           01000010 00851490           01000A64 01000A64           01000010 00000000
    BCD             '        X
 01001B7C      01000010 00000000 R12       01001A2C 01001BCC NAB       00000000 00000000           00000000 00000000
 01001B9C      00000000 00000000           00000000 00000000           00000000 00000000           00A17CBC 00000000
    BCD                                                                                                 @
 01001BBC      00000170 00000000           00000000 00000000
 

ISO-C static and heap areas follow the ISO-C stack frames and are identified by the DLM name.

Figure 49. ISO-C Static Block and Heap Storage Dump

 *ISOC STATIC BLOCK
 01802000    D8E9E9F4 FFFFFF00 0000007C 00000000 E3C8C9E2 40C9E240 E3C8C540 E2E3C1E3       QZZ4............THIS IS THE STAT
 01802020    C9C340C4 C1E3C140 C2D3D6C3 D2404040 40404040 40404040 40404040 40404040       IC DATA BLOCK
 01802040    40404040 40404040 4015F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0                .0000000000000000000000
 01802060    F0F0F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0 F0F0F0F0                0000000000000000000000000000
 
 
 *IN USE HEAP STORAGE
 01801638    827F66C6 00000080 00000000 00000000 00000000 00000000 00000000 00000000       B..F............................
 01801658    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000       ................................
 018016B8    00000000 00000082                                                             .......B
 

If the error occurs in the ISO-C environment, registers 12 and 13 contain the following values:

R12
Address of ISO-C task communications area (TCA)

R13
Address of a stack frame.

Although the contents are not guaranteed, other ISO-C register conventions are:

R1
Parameter list pointer

R3
Function base address

R14
Return address

R15
Routine address or return value.

All other registers are in use by the compiler.

Brief Listing of Errors

The following list briefly describes an error condition and its probable cause.

Table 24. Brief Listing of Errors

Symptom Probable Error
Unresolved Zxx VCONs during linkage editing Including TARGET(TPF) segments in prelink or link-edit steps
Return code 4 from the prelinker DLM call stubs not previously created
Unresolved VCONs to compiler components Different levels of compiler and prelinker
System error CTL-3 - branch to location 0 DLM call stub either not created or not linked
System error CTL-3 - store into program Program compiled with the NORENT parameter
Error during prelinking
WARNING EDC4015: Unresolved
references are detected: @@TRT
Return code 4
The CTRT40 object module (OCO), found in the ACP.OBJ.RELvv PDS, must be copied to the ACP.CLIB.RELvv PDS and renamed to @@TRT.

Using C Function Trace

C function trace provides the ability to trace ISO-C programs. When an ISO-C program has been compiled with the TEST option of one of the C/370 family of compilers supported by the TPF system, C function trace provides the programmer with relevant information to expedite the analysis of C program problems. For information on how to use C function trace and sample trace output see TPF Program Development Support Reference.

Using Link Map Support for C Load Modules

The ZDMAP command allows you to display the link maps for C load modules to help you debug C load modules online. You must use both the offline C load module build tool (CBLD) and the offline loader (TPFLDR) if you want a C load module to have a link map. See "ISO-C Load Module Build Tool (CBLD)" for more information about link map support in the C load module build tool.

The link map consists of a list of object files included in the C load module, a list of C function names in the object files, and the addresses of the object files and C functions.

Link map displays include both main storage addresses and the offsets of C functions into their respective object files. Any time an object file name or function name is displayed, the address of the object file or function is also displayed.

Parameters on the ZDMAP command allow you to request the following:

See TPF Operations for more information about the ZDMAP command.