Figure 1 illustrates a C program that contains a divide-by-zero error. The code was compiled with RENT so static and external variables need to be calculated from the WSA field. The code was compiled with XREF, LIST and OFFSET to generate a listing, which is used to calculate addresses of functions and data. The code was processed by the binder with MAP to generate a binder map, which is used to calculate the addresses of static and external variables.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int statint = 73;
int fa;
void funcb(int *pp);
int main(void) {
int aa, bb=1;
aa = bb;
funcb(&aa);
return(99);
}
void funcb(int *pp) {
int result;
fa = *pp;
result = fa/(statint-73);
return;
}
To debug this routine, use the following steps:
The traceback section of the dump indicates that the exception occurred at offset X'76' within function funcb. This information is used along with the compiler-generated Pseudo Assembly Listing to determine where the problem occurred.
If the TEST compiler option is specified, variable information is in the dump. If the GONUMBER compiler option is specified, statement number information is in the dump. Figure 2 shows the generated traceback from the dump.
CEE3DMP V1 R12.0: Condition processing resulted in the unhandled condition. 05/24/10 6:20:36 PM Page: 1
ASID: 0049 Job ID: JOB23480 Job name: CDIVZERO Step name: STEP1 UserID: HEALY
CEE3845I CEEDUMP Processing started.
Information for enclave main
Information for thread 8000000000000000
Traceback:
DSA Entry E Offset Statement Load Mod Program Unit Service Status
1 CEEHDSP +00004030 CEEPLPKA CEEHDSP D1908 Call
2 funcb +00000076 18 CDIVZERO Exception
3 main +00000064 12 CDIVZERO Call
4 EDCZMINV +000000C2 CEEEV003 Call
5 CEEBBEXT +000001B6 CEEPLPKA CEEBBEXT D1908 Call
DSA DSA Addr E Addr PU Addr PU Offset Comp Date Compile Attributes
1 20FCB358 209C4238 209C4238 +00004030 20061215 CEL
2 20FCB2B0 20900960 20900960 +00000076 20070115 C/C++
3 20FCB208 209008E0 209008E0 +00000064 20070115 C/C++
4 20FCB0F0 20E699EE 20E699EE +000000C2 20061215 LIBRARY
5 20FCB030 20992208 20992208 +000001B6 20061215 CEL
Condition Information for Active Routines
Condition Information for (DSA address 20FCB2B0)
CIB Address: 20FCBC78
Current Condition:
CEE0198S The termination of a thread was signaled due to an unhandled condition.
Original Condition:
CEE3209S The system detected a fixed-point divide exception (System Completion Code=0C9).
Location:
Program Unit: Entry: funcb Statement: 18 Offset: +00000076
Machine State:
ILC..... 0002 Interruption Code..... 0009
PSW..... 078D2400 A09009D8
GPR0..... 00000000_20900A08 GPR1..... 00000000_00000000 GPR2..... 00000000_20FCB2A8 GPR3..... 00000000_2090099A
GPR4..... 00000000_00000000 GPR5..... 00000000_00000001 GPR6..... 00000000_20900B24 GPR7..... 00000000_20900098
GPR8..... 00000000_00000030 GPR9..... 00000000_80000000 GPR10.... 00000000_A0E699E2 GPR11.... 00000000_A0992208
GPR12.... 00000000_209139B0 GPR13.... 00000000_20FCB2B0 GPR14.... 00000000_20914F50 GPR15.... 00000000_00000008
Storage dump near condition, beginning at location: 209009C6
+000000 209009C6 5811E000 504FE000 A71AFFB7 8E400020 1D4158F0 306A4110 D0985000 D0985050 |....&|..x.... .....0.....q&..q&&|
GPREG STORAGE:
Storage around GPR0 (20900A08)
-0020 209009E8 0DEF18F5 58D0D004 58E0D00C 9825D01C 051E0707 00000000 00000008 209000B8 |...5........q...................|
+0000 20900A08 D985A2A4 93A3407E 406C8415 00000000 1CCEA106 00000228 00000178 00000000 |Result = %d.....................|
⋮
The offset (within funcb) of the exception from the traceback (X'76') reveals the divide instruction: DR r4,r1 at that location. Instructions X'66' through X'76' refer to the result = fa/(statint-73); line of the C/C++ routine.
OFFSET OBJECT CODE LINE# FILE# P S E U D O A S S E M B L Y L I S T I N G
000015 | * int funcb(int *pp) {
000000 000015 | funcb DS 0D
.
.
.
000046 50D0 E004 000015 | ST r13,4(,r14)
00004A 18DE 000015 | LR r13,r14
00004C End of Prolog
00004C 58E0 C1F4 000000 | L r14,_CEECAA_(,r12,500)
000016 | * int result;
000017 | * fa = *pp;
000050 5820 1000 000017 | L r2,pp(,r1,0)
000054 5810 3062 000018 | L r1,=Q(statint)(,r3,98)
000058 58F0 3066 000017 | L r15,=Q(fa)(,r3,102)
00005C C000 0000 0026 000000 | LARL r0,F'38'
000062 5840 2000 000017 | L r4,(*)int(,r2,0)
000018 | * result = fa/(statint-73);
000066 5811 E000 000018 | L r1,statint(r1,r14,0)
00006A 504F E000 000017 | ST r4,fa(r15,r14,0)
00006E A71A FFB7 000018 | AHI r1,H'-73'
000072 8E40 0020 000018 | SRDA r4,32
000076 1D41 000018 | DR r4,r1
000019 | * printf("Result = %d\n",result);
000078 58F0 306A 000019 | L r15,=V(printf)(,r3,106)
00007C 4110 D098 000019 | LA r1,#MX_TEMP2(,r13,152)
000080 5000 D098 000019 | ST r0,#MX_TEMP2(,r13,152)
000084 5050 D09C 000019 | ST r5,#MX_TEMP2(,r13,156)
000088 0DEF 000019 | BASR r14,r15
000020 | * return result;
00008A 18F5 000020 | LR r15,r5
000021 | * }
00008C 000021 | @2L3 DS 0H
00008C Start of Epilog
00008C 58D0 D004 000021 | L r13,4(,r13)
000090 58E0 D00C 000021 | L r14,12(,r13)
000094 9825 D01C 000021 | LM r2,r5,28(r13)
000098 051E 000021 | BALR r1,r14
00009A 0707 000021 | NOPR 7
00009C Start of Literals
00009C 00000000 =Q(statint)
0000A0 00000000 =Q(fa)
0000A4 00000000 =V(printf)
0000A8 End of Literals
*** General purpose registers used: 1111110000001111
*** Floating point registers used: 1111111100000000
*** Size of register spill area: 128(max) 0(used)
*** Size of dynamic storage: 168
*** Size of executable code: 156
Constant Area
000000 D985A2A4 93A3407E 406C8415 00 |Result = %d.. |
PPA1: Entry Point Constants
000000 1CCEA106 =F'483303686' Flags
000004 00000228 =A(PPA2-main)
000008 00000178 =A(PPA3-main)
00000C 00000000 =F'0' No EPD
000010 FE000000 =F'-33554432' Register save mask
000014 00000000 =F'0' Member flags
000018 90 =AL1(144) Flags
000019 000000 =AL3(0) Callee's DSA use/8
00001C 0040 =H'64' Flags
00001E 0012 =H'18' Offset/2 to CDL
000020 00000000 =F'0' Reserved
000024 5000003C =F'1342177340' CDL function length/2
000028 FFFFFEC8 =F'-312' CDL function EP offset
00002C 38260000 =F'942014464' CDL prolog
000030 40090033 =F'1074331699' CDL epilog
000034 00000000 =F'0' CDL end
000038 0004 **** AL2(4),C'main'
PPA1 End
⋮
Because this routine was compiled with the RENT option, find the WSA address in the Enclave Control Blocks section of the dump. In this example, this address is X'20914F50'. Figure 4 shows the WSA address.
Enclave Control Blocks:
⋮
WSA address.................20914F50
⋮
⋮
---------------
CLASS C_WSA LENGTH = AC ATTRIBUTES = MRG, DEFER , RMODE=ANY
OFFSET = 0 IN SEGMENT 002 ALIGN = DBLWORD
---------------
CLASS
OFFSET NAME TYPE LENGTH SECTION
0 statint PART 4 statint
8 fa PART 4 fa
10 environ PART 4 environ
18 errno PART 4 errno
⋮
The writable static area is shown in the Enclave Storage section of the dump. For a load module, the writable static area is storage allocated by the C/C++ runtime for the C/C++ user, so it is in the user heap. For a program object, the writable static area is storage allocated by the loader and is shown in the WSA for Program Object(s) section of the dump.
For this example, the program was built as a program object. The writable static area is displayed in the Enclave Storage section of the dump, shown in Figure 6.
Enclave Storage:
⋮
WSA for Program Object(s)
WSA: 20914F50
+000000 20914F50 00000049 00000000 00000001 00000000 2090A880 00000000 00000000 00000000 |..................y.............|
+000020 20914F70 20910260 2091026A 00000000 00000000 00000000 00000000 00000000 00000000 |.j.-.j..........................|
+000040 20914F90 00000001 00000000 00000001 00000000 00000000 00000000 00000000 00000000 |................................|
+000060 20914FB0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
+000080 20914FD0 00000000 00000000 00000000 00000000 2090F6BC 00000000 2090F28C 00000000 |..................6.......2.....|
+0000A0 20914FF0 2090F4A4 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |..4u............................|
⋮