HP 3000 Manuals

Using Debug (continued) [ HP COBOL II/XL Programmer's Guide ] MPE/iX 5.0 Documentation


HP COBOL II/XL Programmer's Guide

Using Debug (continued) 

Debugging Trap Errors 

Debugging trap errors is easier if you have symbol table, verb, and link
maps of your program.

The trap error message contains the program counter (pc) address.  In the
link map, find the value of the pc.  The subprogram in which the trap
error occurred is the symbol of type code with the greatest SYM VALUE not
greater than the pc value.  Subtract that SYM VALUE from the pc value to
get the offset of the trap.

In the verb map for the subprogram in which the trap occurred, find the
statement with the greatest offset not greater than the offset of the
trap.  This is the statement where the trap occurred.

If the subprogram in which the trap occurred is not written in COBOL, the
error message may be misleading.  However, the pc value, link map, and
stack marker trace (which is printed when the program aborts) are
accurate.

If you get the system trap error message DATA MEMORY PROTECTION or
INVALID ADDRESS, recompile your COBOL program with the control option
BOUNDS and rerun it.  You will probably get a COBOL trap, because these
system traps usually result from values out of bounds.

This section gives at least one debugging example for each type of trap.
The types of traps are:

   *   Illegal ASCII or Decimal Digit.
   *   Range Error.
   *   No Size Error.
   *   PERFORM Stack Overflow.
   *   Invalid GO TO.
   *   Address Alignment.[REV BEG]
   *   Intrinsic Function Traps.[REV END]

This section also explains:

   *   Trace traps.

Redirecting Output from Traps.   

The trap examples that follow show output that goes to $STDLIST. The
output comes from two sources, the COBOL run-time library and Debug.[REV
BEG] [REV END]
[REV BEG]


NOTE The examples that follow print the statement number of the trap as Stmt #nnn However, for optimized programs, the statement number appears as ????. This also occurs for statements that generate a large amount of machine instructions. In such cases, see the section "Calculating Code Addresses" in this chapter to determine the statement where the error occurs.
[REV END] Illegal ASCII Digit. In this example, a program with illegal ASCII digits is executed with the COBRUNTIME value A. The effect of other COBRUNTIME values is explained after the example. Given the following compiled source program: 00001 000100$CONTROL MAP,VALIDATE 00003 001000 IDENTIFICATION DIVISION. 00004 002000 PROGRAM-ID. TRAP-ASCII-DIG. 00005 003000 DATA DIVISION. 00006 004000 WORKING-STORAGE SECTION. 00007 005000 01 BAD-VALUE PIC X(4) VALUE "12 4". 00008 006000 01 B REDEFINES BAD-VALUE PIC 9(4). 00009 007000 01 D PIC 9(4). 00010 008000 PROCEDURE DIVISION. 00011 009000 TRAP-TEST. 00012 009100****************************************** 00013 009200* Trap test with illegal ASCII digit * 00014 009300****************************************** 00015 010000 DISPLAY "Should produce illegal ASCII digit.". 00016 011000 ADD 1 TO B. 00017 012000 DISPLAY BAD-VALUE. 00018 013000 DISPLAY "Test case did not abort.". 00019 014000 STOP RUN. The section of the map that shows the addresses of items in WORKING-STORAGE is: [REV BEG] LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY WORKING-STORAGE SECTION 00007 01 BAD-VALUE DP+ 30 4 DISP AN 00008 01 B DP+ 30 4 DISP N 00009 01 D DP+ 34 4 DISP N [REV END] When COBRUNTIME is not set (that is, when it has its default value) or when COBRUNTIME is set to A (Abort), and the program is compiled with the control option VALIDATE, this program produces the following information when run in session mode. (When run in a job stream, the output may look slightly different. When debugging a program, running it in a session is recommended.) :$OLDPASS Should produce illegal ASCII digit. Illegal ASCII digit (COBERR 711) Program file: $OLDPASS.H6OPT2.COBOL74 Trap type = 00000200 (22,00), at pc = 000004D0.000083BF invalid ascii digit Source address = 40200030, Source = '12 4' (hex) Source = '31322034' DEBUG/XL A.01.00 HPDEBUG Intrinsic at: 4d0.0000d1fc print_message$093+$314 $$$$ Trap occurred at: trap_ascii_dig+$74, at Stmt #16 PC=4d0.00007ac0 vloop+$c 0) SP=402210e8 RP=4d0.000083c4 trap_ascii_dig+$7c * 1) SP=402210e8 RP=4d0.00000000 inx_A0000+$14 (end of NM stack) $$$$ The address $40200030 = DP+$28 may be in main, SUBPROGRAM or EXTERNAL The most important pieces of information are flagged by the string "$$$$." The first gives you the number of the statement that preceded the trap. The second gives you the address of the data item that caused the trap. If you look up DP+$28 in the map, you find that the data item BAD-VALUE caused this trap. (Since the output above says that the data item that caused the trap could be in a main program, be in a subprogram, or be an EXTERNAL item, you must study the maps and data of your program to determine that BAD-VALUE is the culprit. The statement number (#16) may also help determine the problem.) Beneath the line flagged "$$$$" above is a stack trace that shows where in your code the program aborted. The highest name on this stack that is the name of one of your programs has the exact address in the program file where the abort occurred. This may be useful if you use Debug. Refer to the MPE XL System Debug Reference Manual for more information. If you change the value of COBRUNTIME and rerun the above program, program behavior changes as described below. COBRUNTIME Value Change in Program Behavior I The trap occurs, but the program ignores it and continues. M The trap occurs, the above trap information is printed, the illegal digit is replaced by a legal digit, and the program continues. N The trap occurs, the illegal digit is replaced by a legal digit, and the program continues. C The trap occurs, the above trap information is printed, and the program continues. [REV BEG] The following example shows an illegal ASCII digit error with an invalid sign. The error occurs when attempting to display variables N4 and N4R. C PAGE 0001 COBOL II/XL HP31500A.04.03 [85] TUE, JUL 9, 1991, 5:18 PM Copyright Hewlett-Packard CO. 1987 00001 001000$CONTROL VALIDATE 00002 001100 IDENTIFICATION DIVISION. 00003 001200 PROGRAM-ID. 00004 001300 COBMAIN. 00005 001400 ENVIRONMENT DIVISION. 00006 001500 DATA DIVISION. 00007 001600 WORKING-STORAGE SECTION. 00008 001700 01 A1 PIC X VALUE SPACES. 00009 001800 01 N1 PIC 99 VALUE 0. 00010 001900 01 N2 PIC 99 VALUE 0. 00011 002000 01 N3 PIC S99 VALUE 0. 00012 002010 01 N4 PIC 999. 00013 002020 01 N4R REDEFINES N4 PIC S999. 00014 002100 PROCEDURE DIVISION. 00015 002200 FIRST-PARA. 00016 002300 MOVE 10 TO N1. 00017 002400 MOVE N1 TO N3. 00018 002500 DISPLAY N1, N3. 00019 002510 MOVE 111 TO N4. 00020 002520 DISPLAY N4, N4R. 00021 002600 STOP RUN. 0 ERROR(s), 0 QUESTIONABLE, 0 WARNING(s) DATA AREA IS 44 BYTES. CPU TIME = 0:00:01. WALL TIME = 0:00:01. [REV END] [REV BEG] 10+10 Illegal ASCII digit (COBERR 711) Program file: $OLDPASS.USER2.COBOL74 Trap type = 00000200 (22,01), at pc = 000000B9.00005E07 invalid ascii digit (S->S) Source address = 4033A0BC, Source = '111' (hex) Source = '313131' DEBUG/XL A.47.01 HPDEBUG Intrinsic at: 678.00351270 cob_trap.print_message+$5c4 $$$$ Trap occurred at: cobmain+$1b4, at Stmt #20 PC=b9.00005e04 cobmain+$1b4 * 0) SP=4033a0f0 RP=b9.00000000 $$inx_A0000+$14 (end of NM stack) $$$$ The address $4033a0bc = SP-$34 is in cobmain (TEMPCELL or $DYNAMIC) ============================================================ **** COB_QUIT 711 **** ABORT: $OLDPASS.USER2.COBOL74 NM SYS a.00944414 dbg_abort_trace+$2c NM USER 678.003502f8 COB_QUIT+$b8 NM SYS a.004403d0 user_trap_caller+$e4 --- Interrupt Marker NM PROG b9.00005e04 cobmain+$1b4 [REV END] Range Error. These errors may occur when a subscript or index references an array out of bounds. Given the following compiled source program: 00001 001000$CONTROL BOUNDS,MAP 00003 001100 IDENTIFICATION DIVISION. 00004 001200 PROGRAM-ID. BOUNDSEXAMPLE. 00005 001300* This program has a subscript out of bounds. 00006 001400 DATA DIVISION. 00007 001500 WORKING-STORAGE SECTION. 00008 001600 01. 00009 001700 05 PIC X. 00010 001800 05 XX PIC X. 00011 001900 01. 00012 002000 05 Y OCCURS 80 TIMES PIC X. 00013 002100 01 Z PIC S9(9) COMP VALUE 0. 00014 002200 PROCEDURE DIVISION. 00015 002300 P1. 00016 002400************************************************** 00017 002500* Trap test with range error * 00018 002600************************************************** 10019 002700 MOVE -5 TO Z. 00020 002800 MOVE Y(Z) TO XX. 00021 002900 DISPLAY "Test case did not abort.". 00022 003000 STOP RUN. The section of the map that shows the addresses of items in WORKING-STORAGE is: LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY WORKING-STORAGE SECTION 00008 01 FILLER DP+ 28 2 DISP AN 00009 05 FILLER DP+ 28 1 DISP AN 00010 05 XX DP+ 29 1 DISP AN 00011 01 FILLER DP+ 2C 50 DISP AN 00012 05 Y DP+ 2C 1 DISP AN 00013 01 Z DP+ 7C 4 COMP NS When COBRUNTIME is not set (that is, when it has its default value) or when COBRUNTIME is set to A (Abort), and the program is compiled with the control option BOUNDS, this program produces the following information when run in a session. (When run in a job stream, the output may look slightly different. When debugging a program, running it in a session is recommended.) :$OLDPASS SUBSCRIPT/INDEX/REFMOD/DEP-ON out of BOUNDS (COBERR 751) Program file: $OLDPASS.H6OPT2.COBOL74 Trap type = 00080000 (12,00), at pc = 00000551.000077CB range error DEBUG/XL A.01.00 HPDEBUG Intrinsic at: 551.0000c594 print_message$093+$314 $$$$ Trap occurred at: boundsexample+$30, at Stmt #20 PC=551.000077c8 boundsexample+$30 * 0) SP=402210d8 RP=551.00000000 (end of NM stack) $$$$ The variable -5 < 1 (limit) The most important pieces of information are flagged by the string "$$$$." The first gives you the number of the statement that preceded the trap. The second gives you the bad value of the index or subscript, compared to the limit. Beneath the line flagged "$$$$" above is a stack trace that shows where in your code the program aborted. The highest name on this stack that is the name of one of your programs has the exact address in the program file where the abort occurred. This may be useful if you use Debug. Refer to the MPE XL System Debug Reference Manual for more information. No Size Error. The No Size Error trap sometimes occurs where it is not possible to specify ON SIZE ERROR, as in an expression in a relational condition. If the same expression were in a COMPUTE statement, the ON SIZE ERROR phrase would execute. In the following compiled source program, division by zero causes the ON SIZE ERROR trap: 0001 001000 identification division. 0002 001100 program-id. zerotrap. 0003 001200 data division. 0004 001300 working-storage section. 0005 001400 77 n pic 999. 0006 001500 77 bad-value pic s999 value zero. 0007 001600 procedure division. 0008 001700 house. 0009 001800********************************************* 0010 001900* Divide by Zero with no Size Error Phrase. * 0011 002000********************************************* 0012 002100 Display "Should give NO SIZE ERROR PHRASE". 0013 002200 Compute n = 1 / BAD-VALUE. 0014 002300 Display "Test case did not abort". 0015 002400 Stop run. When COBRUNTIME is not set (that is, when it has its default value) or when COBRUNTIME is set to A (Abort), this program produces the following information when run in a session. (When run in a job stream, the output may look slightly different. When debugging a program, running it in a session is recommended.) :$OLDPASS Should give NO SIZE ERROR PHRASE No SIZE ERROR phrase (COBERR 747) Program file: $OLDPASS.H6OPT2.COBOL74 Trap type = 00000002 (30,00), at pc = 00000531.0000835B integer divide by 0 DEBUG/XL A.01.00 HPDEBUG Intrinsic at: 531.0000d124 print_message$093+$314 $$$$ Trap occurred at: zerotrap+$a0, at Stmt #13 PC=531.00006774 small_divisor+$8 0) SP=402210f0 RP=531.00008360 zerotrap+$a8 * 1) SP=402210f0 RP=531.00000000 inx_A0000+$14 (end of NM stack) The most important piece of information is flagged by the string "$$$$," which tells you the number of the statement that preceded the trap. Beneath the line flagged "$$$$" above is a stack trace that shows where in your code the program aborted. The highest name on this stack that is the name of one of your programs has the exact address in the program file where the abort occurred. This can be useful if you use Debug. Refer to the MPE XL System Debug Reference Manual for more information. PERFORM Stack Overflow. Each program has a PERFORM stack, used to keep track of which paragraphs are executing and where to return after execution of a paragraph. This stack can overflow if your program has control-flow bugs, as the following example does. It has recursive PERFORM statements. Given the following compiled source program: 00001 001000$CONTROL BOUNDS,VERBS 00003 001100 IDENTIFICATION DIVISION. 00004 001200 PROGRAM-ID. PERFORM-TRAP. 00005 001300 PROCEDURE DIVISION. 00006 001400 TRAP-TEST. 00007 001500 DISPLAY "Should give paragraph stack overflow.". 00008 001600****************************************** 00009 001700* Trap test with recursive performs. * 00010 001800****************************************** 00011 001900 PERFORM PAR-A THROUGH PAR-B. 00012 002000 GO TO COMMON-EXIT. 00013 002100 PAR-A. 00014 002200 PERFORM PAR-B. 00015 002300 PAR-B. 00016 002400 PERFORM PAR-A. 00017 002500 COMMON-EXIT. 00018 002600 DISPLAY "Test case did not abort.". 00019 002700 STOP RUN. Here is the verb map that shows the code offsets of the program statements: PAGE 0002/COBTEXT PERFORM-TRAP STATEMENT OFFSETS Entry = perform_trap STMT OFFSET STMT OFFSET STMT OFFSET STMT OFFSET ... 6 3C 12 80 15 B4 18 E0 7 3C 13 88 16 B4 19 110 11 68 14 88 17 E0 When COBRUNTIME is not set (that is, when it has its default value) or when COBRUNTIME is set to A (Abort), and the program is compiled with the control option BOUNDS, this program produces the following information when run in a session. (When run in a job stream, the output may look slightly different. When debugging a program, running it in a session is recommended.) :$OLDPASS Should give paragraph stack overflow. Paragraph stack overflow (COBERR 748) Program file: $OLDPASS.H6OPT2.COBOL74 Trap type = 00800000 (08,00), at pc = 00000531.00007873 paragraph stack overflow DEBUG/XL A.01.00 HPDEBUG Intrinsic at: 531.0000c64c print_message$093+$314 $$$$ Trap occurred at: perform_trap+$b8, at Stmt #16 PC=531.00007870 perform_trap+$b8 * 0) SP=40221278 RP=531.00000000 (end of NM stack) Perform stack for COBOL program: perform_trap+$b8 Return at end of procedure #2 to perform_trap+$a0 Stmt #14 Return at end of procedure #1 to perform_trap+$cc Stmt #16 Return at end of procedure #2 to perform_trap+$a0 Stmt #14 Return at end of procedure #1 to perform_trap+$cc Stmt #16 Return at end of procedure #2 to perform_trap+$a0 Stmt #14 Return at end of procedure #1 to perform_trap+$cc Stmt #16 : Return at end of procedure #1 to perform_trap+$cc Stmt #16 Return at end of procedure #2 to perform_trap+$a0 Stmt #14 Return at end of procedure #2 to perform_trap+$80 Stmt #11 End of perform stack The statement number preceding the trap is flagged by the string "$$$$" and the contents of the PERFORM stack is printed. The phrase "Return at end of procedure #num" means that the paragraph[REV BEG] num has been called, where paragraph zero is the first paragraph in the source program, paragraph one[REV END] is the second, and so on. (When sections are called, the number of the last paragraph in the section appears.) This PERFORM stack trace also tells you from where the paragraph was called: that is the statement number on the far right. Beneath the line flagged "$$$$" above is a stack trace that shows where in your code the program aborted. The highest name on this stack that is the name of one of your programs has the exact address in the program file where the abort occurred. This can be useful if you use Debug. Refer to the MPE XL System Debug Reference Manual for more information. Invalid GO TO. This example illustrates an invalid GO TO trap, which occurs at an unaltered GO TO statement: 00001 001000$CONTROL BOUNDS 00002 001100 IDENTIFICATION DIVISION. 00003 001200 PROGRAM-ID. TRAPGOTO. 00004 001300 PROCEDURE DIVISION. 00005 001400 TRAP-TEST. 00006 001500******************************************* 00007 001600* Trap test with Invalid Goto * 00008 001700******************************************* 00009 001800 DISPLAY "Should produce illegal goto trap.". 00010 001900 PAR. 00011 002000 GO TO. 00012 002100 PAR2. 00013 002200 ALTER PAR TO PAR2. 00014 002300 COMMON-EXIT. 00015 002400 DISPLAY "Test case did not abort.". 00016 002500 STOP RUN. When COBRUNTIME is not set (that is, when it has its default value) or when COBRUNTIME is set to A (Abort), and the program is compiled with the control option BOUNDS, this program produces the following information when run in a session. (When run in a job stream, the output may look slightly different. When debugging a program, running it in a session is recommended.) :$OLDPASS Should produce illegal goto trap. Invalid GOTO (COBERR 754) Program file: $OLDPASS.H6OPT2.COBOL74 Trap type = 00100000 (11,00), at pc = 00000551.00007817 nil pointer reference DEBUG/XL A.01.00 HPDEBUG Intrinsic at: 551.0000c5ec print_message$093+$314 $$$$ Trap occurred at: trapgoto+$54, at Stmt #11 PC=551.00007814 trapgoto+$54 * 0) SP=402210d8 RP=551.00000000 (end of NM stack) The most important piece of information is flagged by the string "$$$$." It tells you the statement number of the unaltered GO TO statement. Beneath the line flagged "$$$$" above is a stack trace that shows where in your code the program aborted. The highest name on this stack that is the name of one of your programs has the exact address in the program file where the abort occurred. This can be useful if you use Debug. Refer to the MPE XL System Debug Reference Manual for more information. Address Alignment. Address alignment traps are caught by the Link Editor. You must link with PARMCHECK=0 AND purposely ignore the Link Editor warnings to cause one of these traps. This example illustrates parameter misalignment, where a parameter is passed to a COBOL subprogram that is not 32-bit aligned: 00001 001000$CONTROL MAP 00002 001100 IDENTIFICATION DIVISION. 00003 001200 PROGRAM-ID. TRAPMAIN. 00004 001300 DATA DIVISION. 00005 001400 WORKING-STORAGE SECTION. 00006 001500 01. 00007 001600 05 PIC X. 00008 001700 05 XX PIC X. 00009 001800 PROCEDURE DIVISION. 00010 001900 P1. 00011 002000****************************************** 00012 002100* Trap tests with alignment * 00013 002200****************************************** 00014 002300 DISPLAY "Should produce alignment trap.". 00015 002400 CALL "Trapsub" USING XX. 00016 002500 DISPLAY "Test case did not abort.". 00017 002600 STOP RUN. This subsection of the map shows the addresses of items in WORKING-STORAGE. Notice that parameter XX is on an odd byte boundary (DP+29). LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY WORKING-STORAGE SECTION 00006 01 FILLER DP+ 28 2 DISP AN 00007 05 FILLER DP+ 28 1 DISP AN 00008 05 XX DP+ 29 1 DISP AN COBOL subprograms normally assume worst case (byte) alignment, which should never trap. To cause an address alignment trap, you must do one more thing: compile the subprogram with OPTFEATURES = LINKALIGNED (this option generates faster code, which assumes parameters are 32-bit-aligned). Here is the compiled subprogram, called by the above main program: 00001 001000$CONTROL MAP,SUBPROGRAM,BOUNDS 00003 001100$CONTROL OPTFEATURES=LINKALIGNED 00003 001200 IDENTIFICATION DIVISION. 00004 001300 PROGRAM-ID. TRAPSUB. 00005 001400 DATA DIVISION. 00006 001500 LINKAGE SECTION. 00007 001600 01 XX PIC X. 00008 001700 PROCEDURE DIVISION USING XX. 00009 001800 P1. 00010 001900 MOVE "**" TO XX. 00011 002000 EXIT PROGRAM. LINE# LVL SOURCE NAME BASE OFFSET SIZE USAGE CATEGORY LINKAGE SECTION 00007 01 XX P 00 0 1 DISP AN Here is the link command, with parameter checking turned off (if parameter checking is not turned off, the link fails to produce a program file): :link from=strapm,straps;to=ptrapm;PARMCHECK=0 HP Link Editor/XL (HP30315A.00.23) Copyright Hewlett-Packard Co 1986 LinkEd> link from=strapm,straps;to=ptrapm;PARMCHECK=0 INCOMPATIBLE ALIGNMENT: trapsub (STRAPM, STRAPS) (LINKWARN 1504) (PARAMETER #1) The Link Editor tells you which program is being called with the bad parameter. When COBRUNTIME is not set (that is, when it has its default value) or when COBRUNTIME is set to A (Abort), this program produces the following information when run in a session. (When run in a job stream, the output may look slightly different When debugging a program, running it in a session is recommended.) :ptrapm SHOULD PRODUCE ALIGNMENT TRAP (753) Address alignment error (COBERR 753) Program file: PTRAPM.H6OPT2.COBOL74 Trap type = 00200000 (10,00), at pc = 000004D0.0000790F bad address alignment DEBUG/XL A.01.00 HPDEBUG Intrinsic at: 4d0.0000c724 print_message$093+$314 $$$$ Trap occurred at: trapsub+$4c, at ???? PC=4d0.0000790c trapsub+$4c * 0) SP=402212b8 RP=4d0.00007814 trapmain+$54 1) SP=402210d8 RP=4d0.00000000 (end of NM stack) $$$$ Called from: trapmain+$54, at Stmt #15 $$$$ The address $40200031 = DP+$29 may be in main, SUBPROGRAM or EXTERNAL The lines with "$$$$" in the above example indicate: the program where the abort occurred (trapsub), the address in the program with the CALL statement (trapmain), and the address (DP+$29) of the data item in question.


MPE/iX 5.0 Documentation