|
HP OpenVMS Delta/XDelta Debugger Manual
Appendix B Sample DELTA Debug Session on Alpha
This appendix gives an example of using DELTA to debug a program on
OpenVMS Alpha. The C program named LOG uses the system service
SYS$GETJPIW to obtain the PID, process name, and login time of each
process. Although this is an example of using DELTA, most of the
commands in the example could be used in an XDELTA debugging session.
To run this program without error, you need WORLD privilege.
The listing file for LOG is shown in two parts. The C source code part
is shown in Example B-1. The machine code part is shown in
Example B-2.
Example B-1 Listing File for LOG: C Source
Code |
1 #include <descrip.h>
434 #include <jpidef.h>
581 #include <ssdef.h>
1233 #include <starlet.h>
3784 #include <stdio.h>
4117 #include <stdlib.h>
4345
4346 void print_line(unsigned long int pid, char *process_name,
4347 unsigned long int *time_buffer);
4348
4349 typedef struct {
4350 unsigned short int il3_buffer_len;
4351 unsigned short int il3_item_code;
4352 void *il3_buffer_ptr;
4353 unsigned short int *il3_return_len_ptr;
4354 } item_list_3;
4355
4356 #define NUL '\0'
4357
4358 main()
4359 {
4360 static char name_buf[16];
4361 static unsigned long int pid, time_buf[2];
4362 static unsigned short int name_len;
4363
4364 unsigned short int pidadr[2] = {-1, -1};
4365 unsigned long int ss_sts;
4366 item_list_3 jpi_itmlst[] = {
4367 /* Get's login time */
4368 {sizeof(time_buf),
4369 JPI$_LOGINTIM,
4370 (void *) time_buf,
4371 NULL},
4372
4373 /* Get's process name */
4374 {sizeof(name_buf) - 1,
4375 JPI$_PRCNAM,
4376 (void *) name_buf,
4377 &name_len},
4378
4379 /* Get's process ID (PID) */
4380 {sizeof(pid),
4381 JPI$_PID,
4382 (void *) &pid,
4383 NULL},
4384
4385 /* End of list */
4386 {0,
4387 0,
4388 NULL,
4389 NULL}
4390 };
4391
4392 /*
4393 While there's more GETJPI information to process and a catastrophic
4394 error has not occurred then
4395 If GETJPI was successful then
4396 NUL terminate the process name string and
4397 print the information returned by GETJPI
4398 */
4399
4400 while(
4401 (ss_sts = sys$getjpiw(0, &pidadr, 0, &jpi_itmlst, 0, 0, 0)) != SS$_NOMOREPROC &&
4402 ss_sts != SS$_BADPARAM &&
4403 ss_sts != SS$_ACCVIO)
4404 {
4405 if (ss_sts == SS$_NORMAL)
4406 {
4407 *(name_buf + name_len) = NUL;
4408 print_line(pid, name_buf, time_buf);
4409 }
4410 }
4411 exit(EXIT_SUCCESS);
4412 }
4413
4414 void print_line(unsigned long int pid, char *process_name,
4415 unsigned long int *time_buffer)
4416 {
4417 static char ascii_time[12];
4418
4419 struct dsc$descriptor_s time_dsc = {
4420 sizeof(ascii_time) - 1,
4421 DSC$K_DTYPE_T,
4422 DSC$K_CLASS_S,
4423 ascii_time
4424 };
4425 unsigned short int time_len;
4426
4427 /*
4428 Convert the logged in time to ASCII and NUL terminate it
4429 */
4430 sys$asctim(&time_len, &time_dsc, time_buffer, 1);
4431 *(ascii_time + time_len) = NUL;
4432
4433 /*
4434 Output the PID, process name and logged in time
4435 */
4436 printf("\n\tPID= %08.8X\t\tPRCNAM= %s\tLOGINTIM= %s", pid,
4437 process_name, ascii_time);
4438
4439 return;
4440 }
4441 __main(void *p1, void *p2, void *p3, void *p4, void *p5, void *p6)
4442 {
4443 void decc$exit(int);
4444 void decc$main(void *, void *, void *, void *, void *, void *, int *, void **, void **);
4445 int status;
4446 int argc;
4447 void *argv;
4448 void *envp;
4449
4450 decc$main(p1, p2, p3, p4, p5, p6, &argc, &argv, &envp);
4451
4452 status = main
4453 (
4454
4455
4456
4457 );
4458
4459 decc$exit(status);
4460 }
|
Example B-2 Listing File for LOG: Machine
Code |
.PSECT $CODE, OCTA, PIC, CON, REL, LCL, SHR,-
EXE, NORD, NOWRT
0000 print_line:: ; 004414
0000 LDA SP, -80(SP) ; SP, -80(SP)
0004 MOV 1, R19 ; 1, R19 ; 004430
0008 STQ R27, (SP) ; R27, (SP) ; 004414
000C MOV 4, R25 ; 4, R25 ; 004430
0010 STQ R26, 32(SP) ; R26, 32(SP) ; 004414
0014 STQ R2, 40(SP) ; R2, 40(SP)
0018 STQ R3, 48(SP) ; R3, 48(SP)
001C STQ R4, 56(SP) ; R4, 56(SP)
0020 STQ FP, 64(SP) ; FP, 64(SP)
0024 MOV SP, FP ; SP, FP
0028 MOV R27, R2 ; R27, R2
002C STL R17, process_name ; R17, 16(FP)
0030 LDQ R0, 40(R2) ; R0, 40(R2) ; 004419
0034 MOV R16, pid ; R16, R3 ; 004414
0038 LDQ R26, 48(R2) ; R26, 48(R2) ; 004430
003C LDA R16, time_len ; R16, 8(FP)
0040 LDQ R4, 32(R2) ; R4, 32(R2) ; 004423
0044 LDA R17, time_dsc ; R17, 24(FP) ; 004430
0048 STQ R0, time_dsc ; R0, 24(FP) ; 004419
004C LDQ R27, 56(R2) ; R27, 56(R2) ; 004430
0050 STL R4, 28(FP) ; R4, 28(FP) ; 004419
0054 JSR R26, SYS$ASCTIM ; R26, R26 ; 004430
0058 LDL R0, time_len ; R0, 8(FP) ; 004431
005C MOV pid, R17 ; R3, R17 ; 004436
0060 LDQ R27, 88(R2) ; R27, 88(R2)
0064 MOV R4, R19 ; R4, R19
0068 LDQ R26, 80(R2) ; R26, 80(R2)
006C MOV 4, R25 ; 4, R25
0070 ZEXTW R0, R0 ; R0, R0 ; 004431
0074 ADDQ R4, R0, R0 ; R4, R0, R0
0078 LDQ_U R16, (R0) ; R16, (R0)
007C MSKBL R16, R0, R16 ; R16, R0, R16
0080 STQ_U R16, (R0) ; R16, (R0)
0084 LDQ R16, 64(R2) ; R16, 64(R2) ; 004436
0088 LDL R18, process_name ; R18, 16(FP)
008C JSR R26, DECC$GPRINTF ; R26, R26
0090 MOV FP, SP ; FP, SP ; 004439
0094 LDQ R28, 32(FP) ; R28, 32(FP)
0098 LDQ R2, 40(FP) ; R2, 40(FP)
009C LDQ R3, 48(FP) ; R3, 48(FP)
00A0 LDQ R4, 56(FP) ; R4, 56(FP)
00A4 LDQ FP, 64(FP) ; FP, 64(FP)
00A8 LDA SP, 80(SP) ; SP, 80(SP)
00AC RET R28 ; R28
Routine Size: 176 bytes, Routine Base: $CODE + 0000
00B0 main:: ; 004358
00B0 LDA SP, -144(SP) ; SP, -144(SP)
00B4 MOV 48, R17 ; 48, R17 ; 004366
00B8 STQ R27, (SP) ; R27, (SP) ; 004358
00BC STQ R26, 64(SP) ; R26, 64(SP)
00C0 STQ R2, 72(SP) ; R2, 72(SP)
00C4 STQ R3, 80(SP) ; R3, 80(SP)
00C8 STQ R4, 88(SP) ; R4, 88(SP)
00CC STQ R5, 96(SP) ; R5, 96(SP)
00D0 STQ R6, 104(SP) ; R6, 104(SP)
00D4 STQ R7, 112(SP) ; R7, 112(SP)
00D8 STQ R8, 120(SP) ; R8, 120(SP)
00DC STQ FP, 128(SP) ; FP, 128(SP)
00E0 MOV SP, FP ; SP, FP
00E4 MOV R27, R2 ; R27, R2
00E8 LDA SP, -16(SP) ; SP, -16(SP)
00EC LDQ R26, 40(R2) ; R26, 40(R2) ; 004366
00F0 LDQ R18, 64(R2) ; R18, 64(R2)
00F4 LDA R16, jpi_itmlst ; R16, 16(FP)
00F8 JSR R26, OTS$MOVE ; R26, R26
00FC LDA R6, jpi_itmlst ; R6, 16(FP) ; 004401
0100 LDQ R3, -64(R2) ; R3, -64(R2) ; 004370
0104 LDA R7, pidadr ; R7, 8(FP) ; 004401
0108 LDQ R0, 32(R2) ; R0, 32(R2) ; 004364
010C MOV 2472, R8 ; 2472, R8 ; 004401
0110 STL R0, pidadr ; R0, 8(FP) ; 004364
0114 LDA R3, time_buf ; R3, 16(R3) ; 004370
0118 MOV R3, R5 ; R3, R5
011C STL R5, 20(FP) ; R5, 20(FP) ; 004366
0120 LDA R4, 8(R3) ; R4, 8(R3) ; 004376
0124 STL R4, 32(FP) ; R4, 32(FP) ; 004366
0128 LDA R17, 24(R3) ; R17, 24(R3)
012C STL R17, 36(FP) ; R17, 36(FP)
0130 LDA R19, 28(R3) ; R19, 28(R3)
0134 STL R19, 44(FP) ; R19, 44(FP)
0138 L$6: ; 004400
0138 LDQ R26, 48(R2) ; R26, 48(R2) ; 004401
013C CLR R16 ; R16
0140 LDQ R27, 56(R2) ; R27, 56(R2)
0144 MOV R7, R17 ; R7, R17
0148 STQ R31, (SP) ; R31, (SP)
014C CLR R18 ; R18
0150 MOV R6, R19 ; R6, R19
0154 CLR R20 ; R20
0158 CLR R21 ; R21
015C MOV 7, R25 ; 7, R25
0160 JSR R26, SYS$GETJPIW ; R26, R26
0164 CMPEQ ss_sts, 20, R16 ; R0, 20, R16 ; 004402
0168 CMPEQ ss_sts, R8, R17 ; R0, R8, R17 ; 004401
016C CMPEQ ss_sts, 12, R18 ; R0, 12, R18 ; 004403
0170 BIS R17, R16, R17 ; R17, R16, R17 ; 004401
0174 BIS R17, R18, R18 ; R17, R18, R18
0178 BNE R18, L$10 ; R18, L$10 ; 004400
017C CMPEQ ss_sts, 1, R0 ; R0, 1, R0 ; 004405
0180 BEQ R0, L$6 ; R0, L$6
0184 MOV R4, R17 ; R4, R17 ; 004408
0188 LDQ_U R19, 24(R3) ; R19, 24(R3) ; 004407
018C MOV R5, R18 ; R5, R18 ; 004408
0190 LDA R27, -96(R2) ; R27, -96(R2)
0194 EXTWL R19, R3, R19 ; R19, R3, R19 ; 004407
0198 ADDQ R4, R19, R19 ; R4, R19, R19
019C LDQ_U R22, (R19) ; R22, (R19)
01A0 MSKBL R22, R19, R22 ; R22, R19, R22
01A4 STQ_U R22, (R19) ; R22, (R19)
01A8 LDL R16, 28(R3) ; R16, 28(R3) ; 004408
01AC BSR R26, print_line ; R26, print_line
01B0 BR L$6 ; L$6 ; 004405
01B4 NOP ;
01B8 L$10: ; 004400
01B8 LDQ R26, 80(R2) ; R26, 80(R2) ; 004411
01BC CLR R16 ; R16
01C0 LDQ R27, 88(R2) ; R27, 88(R2)
01C4 MOV 1, R25 ; 1, R25
01C8 JSR R26, DECC$EXIT ; R26, R26
01CC MOV FP, SP ; FP, SP ; 004412
01D0 LDQ R28, 64(FP) ; R28, 64(FP)
01D4 MOV 1, R0 ; 1, R0
01D8 LDQ R2, 72(FP) ; R2, 72(FP)
01DC LDQ R3, 80(FP) ; R3, 80(FP)
01E0 LDQ R4, 88(FP) ; R4, 88(FP)
01E4 LDQ R5, 96(FP) ; R5, 96(FP)
01E8 LDQ R6, 104(FP) ; R6, 104(FP)
01EC LDQ R7, 112(FP) ; R7, 112(FP)
01F0 LDQ R8, 120(FP) ; R8, 120(FP)
01F4 LDQ FP, 128(FP) ; FP, 128(FP)
01F8 LDA SP, 144(SP) ; SP, 144(SP)
01FC RET R28 ; R28
Routine Size: 336 bytes, Routine Base: $CODE + 00B0
0200 __main:: ; 004441
0200 LDA SP, -48(SP) ; SP, -48(SP)
0204 MOV 9, R25 ; 9, R25 ; 004450
0208 STQ R27, (SP) ; R27, (SP) ; 004441
020C STQ R26, 24(SP) ; R26, 24(SP)
0210 STQ R2, 32(SP) ; R2, 32(SP)
0214 STQ FP, 40(SP) ; FP, 40(SP)
0218 MOV SP, FP ; SP, FP
021C LDA SP, -32(SP) ; SP, -32(SP)
0220 MOV R27, R2 ; R27, R2
0224 LDA R0, argc ; R0, 16(FP) ; 004450
0228 LDQ R26, 48(R2) ; R26, 48(R2)
022C LDA R1, argv ; R1, 12(FP)
0230 STQ R0, (SP) ; R0, (SP)
0234 LDA R0, envp ; R0, 8(FP)
0238 STQ R1, 8(SP) ; R1, 8(SP)
023C LDQ R27, 56(R2) ; R27, 56(R2)
0240 STQ R0, 16(SP) ; R0, 16(SP)
0244 JSR R26, DECC$MAIN ; R26, R26
0248 LDA R27, -96(R2) ; R27, -96(R2) ; 004452
024C BSR R26, main ; R26, main
0250 LDQ R27, 40(R2) ; R27, 40(R2) ; 004459
0254 MOV status, R16 ; R0, R16
0258 MOV 1, R25 ; 1, R25
025C LDQ R26, 32(R2) ; R26, 32(R2)
0260 JSR R26, DECC$EXIT ; R26, R26
0264 MOV FP, SP ; FP, SP ; 004460
0268 LDQ R28, 24(FP) ; R28, 24(FP)
026C LDQ R2, 32(FP) ; R2, 32(FP)
0270 LDQ FP, 40(FP) ; FP, 40(FP)
0274 LDA SP, 48(SP) ; SP, 48(SP)
0278 RET R28 ; R28
Routine Size: 124 bytes, Routine Base: $CODE + 0200
|
The .MAP file for the sample program is shown in Example B-3. Only the
Program Section Synopsis with the psect, module, base address, end
address, and length are listed.
Example B-3 .MAP File for the Sample
Program |
+--------------------------+
! Program Section Synopsis !
+--------------------------+
Psect Name Module Name Base End Length
---------- ----------- ---- --- ------
$LINKAGE 00010000 000100FF 00000100 ( 256.)
LOG 00010000 000100FF 00000100 ( 256.)
$LITERAL 00010100 00010158 00000059 ( 89.)
LOG 00010100 00010158 00000059 ( 89.)
$READONLY 00010160 00010160 00000000 ( 0.)
LOG 00010160 00010160 00000000 ( 0.)
$INIT 00020000 00020000 00000000 ( 0.)
LOG 00020000 00020000 00000000 ( 0.)
$UNINIT 00020000 0002002F 00000030 ( 48.)
LOG 00020000 0002002F 00000030 ( 48.)
$CODE 00030000 0003027B 0000027C ( 636.)
LOG 00030000 0003027B 0000027C ( 636.)
|
The DELTA debug session is shown in Example B-4.
Example B-4 DELTA Debugging Session of the
Sample Program |
$ DEFINE LIB$DEBUG SYS$LIBRARY:DELTA (1)
$ RUN/DEBUG LOG (2)
Alpha/VMS DELTA Version 1.5 (3)
Brk 0 at 00030200
00030200! LDA SP,#XFFD0(SP) 30000,1;X
X1 164! CMPEQ R0,#X14,R16 .;B (4)
X1 1AC! BSR R26,#XFFFF94 .;B (5)
;P
Brk 1 at 00030164 (6)
X1+00000164! CMPEQ R0,#X14,R16 R0/ 00000001 ;P
Brk 2 at 000301AC
X1+000001AC! BSR R26,#XFFFF94 O
PID= 00000021 PRCNAM= SWAPPER LOGINTIM= 00:00:00.00 (7)
X1+000001B0! BR R31,#XFFFFE1 ;P
Brk 1 at 00030164
X1+00000164! CMPEQ R0,#X14,R16 R0/ 00000001 ;P
Brk 2 at 000301AC
X1+000001AC! BSR R26,#XFFFF94 O (8)
PID= 00000024 PRCNAM= ERRFMT LOGINTIM= 16:24:01.03
X1+000001B0! BR R31,#XFFFFE1 ;P
Brk 1 at 00030164
X1+00000164! CMPEQ R0,#X14,R16
;B
1 00030164
2 000301AC
0,1;B
;B
2 000301AC
;P
Brk 2 at 000301AC (9)
X1+000001AC! BSR R26,#XFFFF94 O
PID= 00000025 PRCNAM= OPCOM LOGINTIM= 16:24:02.56
X1+000001B0! BR R31,#XFFFFE1 ;P
Brk 2 at 000301AC (10)
X1+000001AC! BSR R26,#XFFFF94 O
PID= 00000026 PRCNAM= AUDIT_SERVER LOGINTIM=16:24:03.66
X1+000001B0! BR R31,#XFFFFE1 ;P
Brk 2 at 000301AC (11)
X1+000001AC! BSR R26,#XFFFF94 X1 84! LDQ R16,#X0040(R2)
[Linefeed] (12)
X1+00000088! LDL R18,#X0010(FP) [Linefeed]
X1+0000008C! JSR R26,(R26) .;B (13)
;B
1 0003008C
2 000301AC
;P (14)
Brk 1 at 0003008C (15)
X1+0000008C! JSR R26,(R26) O
PID= 00000027 PRCNAM= JOB_CONTROL LOGINTIM= 16:24:06.83
X1+00000090! BIS R31,FP,SP ;P
Brk 2 at 000301AC
X1+000001AC! BSR R26,#XFFFF94 ;P
Brk 1 at 0003008C (16)
X1+0000008C! JSR R26,(R26) O
PID= 00000028 PRCNAM= NETACP LOGINTIM= 16:24:22.86
X1+00000090! BIS R31,FP,SP ;P
Brk 2 at 000301AC
X1+000001AC! BSR R26,#XFFFF94
;B
1 0003008C
2 000301AC
0,2;B
0,1;B
;B
;P
PID= 00000029 PRCNAM= EVL LOGINTIM= 16:24:26.67
PID= 0000002A PRCNAM= REMACP LOGINTIM= 16:24:38.21
PID= 0000002B PRCNAM= LATACP LOGINTIM= 16:24:43.18
PID= 0000004C PRCNAM= GODDARD LOGINTIM= 07:40:49.34
PID= 0000002D PRCNAM= SYMBIONT_0001 LOGINTIM= 16:25:47.54
PID= 0000002F PRCNAM= MCCORMICK LOGINTIM= 16:27:45.27
Exit 00000001
8002228C! ADDL R15,SP,SP EXIT
|
- DELTA is enabled as the debugger.
- The example program LOG is invoked with
DELTA.
- DELTA displays a version number and the
first executable instruction. The base address of the program
(determined from the map file) is virtual address 30000. The base
address is placed in base register 1 with ;X. Now references to an
address can use the address offset notation. For example, a reference
to the first instruction is X1+200 (or the base address 30000 + offset
200). Also, DELTA displays some address locations as offsets to the
base address.
- The instruction at address 30164 is
displayed in instruction mode using !. Its address location is
expressed as the base address plus an offset. In the listing file, the
offset is 164. (This is the point where the return status from
SYS$GETJPIW is checked.) The base address in base address register X1
is 30000. The address reference, then, is X1+164. Note the + sign is
implied when not specified.
A simple breakpoint is set at that
address using the ;B command. The address reference for ;B is the .
symbol, representing the current address. X1+164;B would have done the
same thing.
- The same commands (! command to view the
instruction and ;B to set a breakpoint) are repeated for the
instruction at offset 1AC. (This is the point at which the print_line
function is called.)
- Program execution halts at the first
breakpoint. DELTA displays the breakpoint message (Brk 1 at 00030164)
with the breakpoint number 1 and the virtual address. The virtual
address is 30164, which is the base address (30000) plus the offset
164. DELTA then displays the instruction in instruction mode (CMPEQ
R0,#X14,R16). The contents of the general register 0 are displayed with
the / command. DELTA displays the contents of R0, which is 1. Program
execution continues using the ;P command.
- The function print_line is executed, and the
output (PID, process name, and login time) is displayed.
- The O command halts program execution at the
instruction where the function returns control (BR R31,#XFFFFE1). (This
is the point at which control passes to checking the conditions of the
while loop.) Program execution continues with ;P.
- Breakpoint 2 is encountered. DELTA displays
the breakpoint message, and the instruction. The function is executed
with the O command and the function output is displayed. The next
instruction where the function returns control is displayed. Program
execution continues with the ;P command.
- Breakpoint 2 is encountered again. DELTA
displays the breakpoint message, and the instruction. The function is
executed with the O command and the function output is displayed. The
next instruction where the function returns control is displayed.
Program execution continues with the ;P command.
- Breakpoint 2 is encountered again. The
instruction at offset 84 (in print_line) is displayed using !. This
instruction is part of the setup for the call to the printf function.
- Successive address locations are displayed
by pressing the Linefeed key two times. These instructions are the
remainder of the setup and the call to printf.
- A breakpoint at X1+8C (the current address)
is set using the ;B command. This breakpoint is in the function
print_line. The . symbol represents the current address. Note that
breakpoint 1 was cleared earlier and is now reused by DELTA for the new
breakpoint.
- Program execution continues with the ;P
command.
- Program execution stops at the new
breakpoint 1, which is in the print_line function. DELTA displays the
breakpoint message and the instruction at the new breakpoint. The O
command halts program execution at the instruction where the function
returns control, stepping over the routine call. Note the O command
must be used in this case, as opposed to the ;P command, because the
printf function resides in read-only protected memory. Program
execution is continued with the ;P command.
- Program execution stops at breakpoint 1 in
the print_line function. Program execution is continued using a
combination of the O and ;P commands.
|