Sourceless Debugging without Breakpoints
Related Topics
- On a blank screen, type XPED and press Enter. This activates Code Debug CICS for your terminal, turns on the abend trap option, and displays the Primary Menu as shown in Primary Menu (XPED/XPRT).
Primary Menu (XPED/XPRT)
COMMAND ===>
MODULE: CSECT:
0 SESSION PROFILE - Set default session attributes
1 SESSION CONTROL - Analyze summary of session events
2 DEBUGGING FACILITIES - Interactively debug application programs
5 FILE UTILITY - Access datasets, temp stg, trans data, DLI, DB2
7 ABEND-AID FOR CICS - Interface to Abend-AID for CICS
C CODE COVERAGE - Interface to Code Coverage
G XCHANGE/CICS - Interface to Xchange CICS Facilities
X EXIT - Exit
To set breakpoints in your program or keep specific data fields,
enter your program name and use either the SOURCE command or PF key.
For Online Technical Support refer to: www.bmc.com/support
This text is specified in the MENUMSG global parameter.
NOTICE: Press PF2/PF14 to display the Copyright/Trade Secret Notice
Code Debug CICS is now turned ON and ready to intercept any abends associated with your terminal and programs.
2. To enable the display of the OFFSET field in Assembler programs, type SET JUST OFF in the COMMAND field and press Enter.
3. Type PSEUDOSOURCE CWDEMC in the COMMAND line and press Enter. This automatically transfers you to the Source Listing screen (2.L) and displays the pseudo-listing created. This is shown in following figure. Press Clear to return to CICS to start your test.
Source Listing Screen with CWDEMC Pseudo-Listing
COMMAND ===> SCROLL ===> CSR
MODULE: CWDEMC ********** PseudoSource listing has been created **********
------ --------------------------------------------------------------------->
000005 00000070 90EB D00C STM 14,11,X'00C'(13)
000006 00000074 58E0 D04C L 14,X'04C'(0,13)
000007 00000078 4100 E218 LA 0,X'218'(0,14)
000008 0000007C 5500 C314 CL 0,X'314'(0,12)
000009 00000080 4140 F040 LA 4,X'040'(0,15)
000010 00000084 4720 F014 BP X'014'(0,15)
000011 00000088 58F0 C280 L 15,X'280'(0,12)
000012 0000008C 90F0 E048 STM 15,0,X'048'(14)
000013 00000090 9210 E000 MVI X'000'(14),X'10'
000014 00000094 50D0 E004 ST 13,X'004'(0,14)
000015 00000098 18DE LR 13,14
000016 0000009A 5800 C1F4 L 0,X'1F4'(0,12)
000017 0000009E 5000 D214 ST 0,X'214'(0,13)
000018 000000A2 5810 D214 L 1,X'214'(0,13)
000019 000000A6 5820 472C L 2,X'72C'(0,4)
000020 000000AA 4152 1000 LA 5,X'000'(2,1)
000021 000000AE 5860 4730 L 6,X'730'(0,4)
000022 000000B2 9200 D0B8 MVI X'0B8'(13),X'00'
000023 000000B6 9200 D0BC MVI X'0BC'(13),X'00'
000024 000000BA 9200 D0BD MVI X'0BD'(13),X'00'
4. On a blank CICS screen, type XCCC or your transaction ID and press Enter. This displays the Demonstration Transaction screen shown in following.
Demonstration Transaction Screen
*** Compuware Corporation ***
Demonstration Transaction (C)
Enter desired employee above:
00001 - Causes ASRA Abend
00003 - Causes a write to temporary storage
00004 - Starts up XCCC as an asynchronous task
00005 - Used to show multiple CSECT support: ASM subroutine
00006 - Used to show multiple CSECT support: C subroutine
00007 - Used to show multiple MODULE support: ASM fetchable subroutine
00008 - Used to show multiple MODULE support: C fetchable subroutine
00009 - Used to show multiple MODULE support: ASM DLL subroutine
00010 - Used to show multiple MODULE support: C DLL subroutine
00333 - Causes a storage violation of an SAA
00999 - Ends normally
5. To cause an ASRA abend in CWDEMC, type 00001 and press Enter.
When you used the PSEUDOSOURCE command for CWDEMC, it creates a pseudo-listing that appears to Code Debug CICS as a program that has been processed with the Assembler Language Processor. In this case, the Source Listing screen is displayed as shown in following figure. You can see the resulting abend was an ASRA, a data exception that occurred at statement 1870 in the pseudo-listing. The ASRA occurred on a multiply decimal (MP) instruction.
Source Listing Screen (2.L)
COMMAND ===> SCROLL ===> CSR
MODULE: CWDEMC CSECT: CWDEMC COMPILED: 14 NOV 2006 - 14:54:47
------ ------------------------------ ASRA (DATA EXCEPTION) at CWDEMC.1870 ->
001865 00001BEA D202 D0D8 D2C8 MVC X'0D8'(3,13),X'2C8'(13)
001866 00001BF0 47F0 4488 B X'488'(0,4)
001867 00001BF4 D203 D0D4 689F MVC X'0D4'(4,13),X'89F'(6)
001868 00001BFA D202 D0D8 68A3 MVC X'0D8'(3,13),X'8A3'(6)
001869 00001C00 F853 D2C8 D0D4 ZAP X'2C8'(6,13),X'0D4'(4,13)
=====> 00001C06 FC51 D2C8 D0D0 MP X'2C8'(6,13),X'0D0'(2,13)
001871 00001C0C D205 D0DC D2C8 MVC X'0DC'(6,13),X'2C8'(13)
001872 00001C12 F885 D2CE D0DC ZAP X'2CE'(9,13),X'0DC'(6,13)
001873 00001C18 FC82 D2CE D0D8 MP X'2CE'(9,13),X'0D8'(3,13)
001874 00001C1E D208 D2D7 D2CE MVC X'2D7'(9,13),X'2CE'(13)
001875 00001C24 91F0 D2D7 TM X'2D7'(13),X'F0'
001876 00001C28 4780 44C0 BZ X'4C0'(0,4)
001877 00001C2C F080 D2D7 0001 SRP X'2D7'(9,13),X'001'(1,0)
001878 00001C32 F080 D2D7 0FFF SRP X'2D7'(9,13),X'FFF'(1,0)
001879 00001C38 F8F8 D2E0 D2D7 ZAP X'2E0'(16,13),X'2D7'(9,13)
001880 00001C3E F0F0 D2E0 000F SRP X'2E0'(16,13),X'00F'(1,0)
001881 00001C44 D20F D258 D2E0 MVC X'258'(16,13),X'2E0'(13)
001882 00001C4A 4170 D258 LA 7,X'258'(0,13)
001883 00001C4E F8F2 D268 68B1 ZAP X'268'(16,13),X'8B1'(3,6)
001884 00001C54 4120 D275 LA 2,X'275'(0,13)
Since an ASRA took place on a MP instruction, there is a good chance that one or both of the multipliers contain invalid packed data. To test this theory, you can view the data. First, look at the instruction MP X'2C8'(6,13),X'0D0'(2,13). Since an MP instruction utilizes an IBM SS format, you can determine the first operand is 6 bytes long and is located X'2C8' off register 13. The second operand is 2 bytes long and located at X'0D0' off register 13. However, as we will see later, these offsets may not actually point to the fields in error. The next step is to find out where the data fields being multiplied originated.
Notice the interrupt offset is x'1C06'. See to your hardcopy of the compiler listing to locate the statement nearest to offset X'1C06' (following figure). In our example, the LIST compiler option was used, so we need to see to the Pseudo Assembler Listing section. Look for the closest offset that is less than or equal to the interrupt offset, and matches the MP instruction object code FC51 D2C8 D0D0.
Assembler Listing (LIST) from Compiler Listing
001878 | * dTaxRate = pPayrollParms -> dCurrentTaxRate;
001BC0 5810 D0CC 001878 | L r1,pPayrollParms(,r13,204)
001BC4 F821 D1B0 1008 001878 | ZAP #pdr5@432_11(3,r13,432),.._PayrollParms.dCurrentTaxRate(2,r1,8)
001BCA D202 D0D8 D1B0 001878 | MVC dTaxRate(3,r13,216),#pdr5@432_11(r13,432)
001879 | *
001880 | * dGrossPay = dHoursWorked * dHourlyRate;
001BD0 F853 D1B3 D0D4 001880 | ZAP #pdr10@435_11(6,r13,435),dHourlyRate(4,r13,212)
001BD6 FC51 D1B3 D0D0 001880 | MP #pdr10@435_11(6,r13,435),dHoursWorked(2,r13,208)
001BDC D205 D0DC D1B3 001880 | MVC dGrossPay(6,r13,220),#pdr10@435_11(r13,435)
001881 | *
001882 | * dGrossTax = dGrossPay * dTaxRate / 100.0d;
001BE2 F885 D1B9 D0DC 001882 | ZAP #pdr16@441_11(9,r13,441),dGrossPay(6,r13,220)
001BE8 FC82 D1B9 D0D8 001882 | MP #pdr16@441_11(9,r13,441),dTaxRate(3,r13,216)
001BEE D208 D1C2 D1B9 001882 | MVC #pdr16@450_11(9,r13,450),#pdr16@441_11(r13,441)
001BF4 91F0 D1C2 001882 | TM #pdr16@450_11(r13,450),240
In our example, line number 1880 contains an MP statement at offset x'1BD6'. It exactly matches the object code where the abend occurred. Therefore the line number we will look for in the source listing is 1880.
It is also important to note the first offset associated with line 1880 is x'1BD0'. When resuming in high-level languages, Code Debug CICS automatically resumes at the start of a statement, not the abend point. When using sourceless debugging however, it is your responsibility to specify the correct resume offset.
We can also see that the program is trying to multiply dHoursWorked by dHourlyRate. One or both of these fields contain invalid data that caused the exception.
We can verify this by finding line number 1880. Indeed line 1880 is the line where the abend occurred.
Source Listing from Compiler Listing
LINE STMT
SEQNBR
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+..*
1877 | | 11532
1878 383 | dTaxRate = pPayrollParms -> dCurrentTaxRate; | 11533
1879 | | 11534
1880 384 | dGrossPay = dHoursWorked * dHourlyRate; | 11535
1881 | | 11536
1882 385 | dGrossTax = dGrossPay * dTaxRate / 100.0d; | 11537