HP 9000 Computer Systems ADB Tutorial ABCDE HP Part No. 92432-90005 Printed in U.S.A.
The information contained in this document is subject to change without notice. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or for incidental or consequential damages in connection with the furnishing, performance, or use of this material.
Printing History New editions are complete revisions of the manual. Update packages, which are issued between editions, contain additional and replacement pages to be merged into the manual by the customer. The dates on the title page change only when a new edition or a new update is published. No information is incorporated into a reprinting unless it appears as a prior update; the edition does not change when an update is incorporated.
Preface This tutorial describes the use of ADB, a program that you can use to debug assembly language programs on Precision Architecture RISC (PA-RISC) machines. It also presents the ADB command format, and explains how to debug C programs, set breakpoints, and use maps. A complete command summary is provided following the tutorial. This manual assumes that you, the reader, are experienced in assembly language programming. In addition, you should have a working knowledge of the HP-UX operating system.
Conventions UPPERCASE In a syntax statement, commands and keywords are shown in uppercase characters. The characters must be entered in the order shown; however, you can enter the characters in either upper or lowercase.
Conventions (continued) [ . .. ] | . .. | . .. 4 4 5 base pre xes In a syntax statement, horizontal ellipses enclosed in brackets indicate that you can repeatedly select the element(s) that appear within the immediately preceding pair of brackets or braces. In the example below, you can select Parameter zero or more times. Each instance of Parameter must be preceded by a comma: [,Parameter][...
Contents 1. ADB Tutorial Invoking ADB . . . . . . . . . . . Using ADB Interactively . . . . . . . Displaying Information . . . . . . . Debugging C Programs . . . . . . . Debugging a Core Image . . . . . . Setting Breakpoints . . . . . . . . Advanced Breakpoint Usage . . . Maps . . . . . . . . . . . . . . . Variables and Registers . . . . . . . Formatted Dumps . . . . . . . . . Patching . . . . . . . . . . . . . . Debugging Already Running Processes . System Dependencies . . . . . . . . Command Summary . .
Figures 1. 2. 3. 4. 5. 6. 7. C Program with a Pointer Bug . . . . . . . . ADB Output from the Program in Figure 1 . . C Program to Decode Tabs . . . . . . . . . ADB Output from C Program Shown in Figure 3 ADB Output for Map Command . . . . . . . Simple C Program to Illustrate Patching . . . . ADB Output Illustrating Patching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ADB Tutorial ADB is a debugging program that operates on assembly language programs. It allows you to look at object les and \core" les that result from aborted programs, to print output les in a variety of formats, to patch les, and to run programs with embedded breakpoints. This tutorial provides examples of these and other ADB features. Invoking ADB You invoke ADB by executing the adb(1) command. The syntax is: adb [-w] [-k] [-Idir] [-Ppid] [obj le [core le]] where: -w Permits writing to the object le.
Supplying a minus sign (-) for a le's name means \ignore this argument," as in: adb a.out - To write to the object le while ignoring the core le, you could type: adb -w a.out - To debug a currently running process, invoke ADB by typing: adb -Ppid a.out The pid or \process identi er" can be obtained using the ps(1) command. Because ADB intercepts keystrokes, you cannot use a quit signal to exit from ADB. You must use the explicit ADB request $q or $Q (or 4CONTROL5 D) to exit from ADB.
Using ADB Interactively You work interactively with ADB by entering requests. The general form for a request is: [address] [,count] [command] [modi er] ADB maintains a current address, called \dot". This address is similar in function to the current pointer in the HP-UX editor, vi(1) . When you supply an address , ADB sets dot to that location. ADB then executes any command you entered count times. You can enter the address and count values as expressions.
Table 2 lists some commonly used ADB commands and their meaning. Table 2. Commonly Used ADB Commands Command ? Prints contents from obj / Prints contents from core = Prints value of \dot" (.). : Breakpoint control. $ Miscellaneous requests. ; Request separator. ! Escapes to shell. 4CONTROL5 4 ADB Tutorial Description C le . le . Terminates any ADB command.
Displaying Information You can request ADB to examine locations in either the object le or the core le. The ? request examines the contents of the object le, while the / request examines the core le. Once you initiate a process (using either the :r or :e command), both ? and / refer to locations in the address space of the running process. Following either the ? or / request, you can specify a format that ADB should use to print this information. Table 3 lists some commonly used format commands. Table 3.
In another example, to print the rst four bytes as a hexadecimal number then the next four bytes as a decimal number, you would type the request: ints/XD In this case, ADB still sets dot to ints but the dot increment is now eight bytes. The newline command is a special command that repeats the previous command. The newline command also uses the value of dot increment, but the command may not always have meaning.
You can also use the = command to convert from one base to another. For example, you can print the value \0x32" in octal, hexadecimal, and decimal notation by typing: 0x32=oxd ADB \remembers" complicated format requests for each of the ?, /, and = commands.
Debugging C Programs The following examples illustrate various features of ADB. Certain parts of the output such as machine addresses may depend on the hardware being used, as well as how the program was linked whether shared , unshared , or demand loaded . Debugging a Core Image The C program listed in Figure 1 shows some of the useful information that you can obtain from a core le.
$c sqr() from main+30 main() from _start+18 _start() from $START$+30 $r pcoqh 0xD2B sqr+7 pcoqt 0xD2F sqr+0xB rp 0xCEB main+33 arg0 1 arg1 sp 68023250 ret0 r1 40001800 r3 r6 68023644 r7 r10 0xFFF88000 r11 r14 0xFFFFB400 r15 r18 1BB58 r19 r22 0 r31 sr1 0 sr2 sqr+4? sqr+4: 0xE601095
The pcoqh register indicates that the program failed at sqr+4 (remember to ignore the lower two bits). To print the actual instruction that failed, you can list the instruction and its o set by typing the request: sqr+4?i or:
Setting Breakpoints The C program shown in Figure 3, which changes tabs into blanks, is adapted from a program in the book Software Tools . #include
/* Tabpos return YES if col is a tab stop */ tabpos(col) int col; { if(col > MAXLINE) return(YES); else return(tabs[col]); } /* Settab - Set initial tab stops */ settab(tabp) int *tabp; { int i; } for(i = 0; i<= MAXLINE; i++) (i%TABSP) ? (tabs[i] = NO) : (tabs[i] = YES); Figure 3. C Program to Decode Tabs (continued) After compiling the program into an object le called expand, trying to run the program produces a segmentation violation.
Figure 4 lists an interactive session with ADB for the program listed in Figure 3.
fopen:b #define MAXLINE 80 breakpoint tabpos: ldo 50(r0),r19 :d* :c ...
You can print the location of each breakpoint by typing: $b Notice that the display lists a count eld. ADB bypasses a breakpoint \count - 1" times before it stops execution. A command eld indicates which requests ADB should execute each time it encounters that breakpoint. To run the program, type: :r ADB informs you that it has encountered a breakpoint at setbuf, and it prints the instruction at that address.
You can run the program once again, wait for ADB to encounter the breakpoint at fopen, and then print the argument registers. For illustrative purposes let's print the arguments with breakpoint commands by typing: fopen:b
The array looks correct, so examine the value of col and the operation of the subroutine tabpos. To print the value of col (arg0) at every call to tabpos, you can type the request: tabpos,-1:b
Maps HP-UX supports several executable le formats such as shared , unshared , and demand-loaded that tell the loader how to load a program le. Currently, only shared text les are supported on PA-RISC systems. In shared les, instructions are separated from data, and the text space or instructions are shared when several users are running the process concurrently. Note that once a breakpoint is executed, a private copy of the program's text is used by ADB.
Variables and Registers ADB provides a set of variables for programmers to use. Each variable name consists of a single letter or digit. For example, to set the variable \5" to the hexadecimal value 32, you use the \greater than" sign (>) as follows: 0x32>5 You can then use this variable in other requests. For example, to print the value of the variable \5" in hexadecimal format, you use the \less than" sign (<) as follows: <5=X ADB sets the value of other variables.
You can use variables for such purposes as counting the number of times a routine is called. For example, to count the number of times that the routine tabpos is called in the program listed in Figure 3, you would type the requests: 0>5 tabpos,-1:b <5+1 >5 :r <5=U The \0>5" command sets the variable 5 to zero. The \tabpos,-1:b <5+1 >5" command sets a breakpoint at tabpos.
Formatted Dumps You can combine ADB formatting commands to provide elaborate displays. The following examples illustrate this. To print four octal half-words followed by their ASCII interpretation from the data space of the core image le, you would type:
Patching You can patch les with ADB by using the \write" request (w or W). You often use this request in conjunction with the \locate" request (l or L). The syntax for both requests is: [?/] [lL] value [?/] [wW] value The l request matches on two bytes, and the w request writes two bytes; whereas the L request matches on four bytes, and the W request writes four bytes. The value eld for both requests is an expression, so decimal and octal numbers, as well as character strings, are supported.
Assuming that you had lost the source le for this \valuable" piece of code, you could patch the object code using ADB. You call ADB with the command: adb -w hello - Then you can nd which instruction to modify by printing the rst eight instructions of main. main,8?i You nd the required instruction is at main+18 (hexadecimal).
Note that ADB prints the old and new value when you request a write. When you reprint the instruction, you see that you patched it correctly. This sort of patching requires a knowledge of the machine-level format, or a willingness to experiment. Remember that if you had started the process with :r or :e before you issued the write command, the patch would have been made in the process' address space, not in the object le itself. Refer to Figure 7.
Debugging Already Running Processes The -P option allows ADB to \adopt" an errant process as if it had been originally run under the control of the debugger. The user can then examine it, and detach from it when debugging is completed. After ADB detaches from the process, the program resumes execution, no longer under the control of ADB.
Running ps(1) after exiting ADB shows that the process continues executing after ADB detaches from it. ps Note PID 5428 4326 4126 TTY ttyq6 ttyq6 ttyq6 TIME 0:01 11:14 0:03 COMMAND ps a.out csh It is not possible to use the -w and -P options together. It is an error to open a le for writing when it is already open for execution.
System Dependencies Below is a list of some system dependencies of which you should be aware. To increase run-time execution speed, stack-frame context is kept to a minimum. In particular, the previous stack pointer and the return pointer are not necessarily written to memory locations on the stack itself. Additional information necessary to perform stack unwinds resides in the object le.
Command Summary Breakpoint and Program Control Table 5. Breakpoint and Program Control Command Description :b Set breakpoint at dot. :c Continue running program. :d Delete breakpoint. :k Kill the program being debugged. :r Run object le under ADB control. :s Single step through program. Calling the Shell Table 6. Calling the Shell Command Description Call shell to read remainder of line. ! Assignment to Variables Table 7.
Formatted Printing Commands Table 8. Formatted Printing Commands Command Description ? format Print from object le according to format. / format Print from core le according to format. = format Print the value of dot. ?w expression Write expression to object le. /w expression Write expression to core le. ?l expression Locate expression in object le. /l expression Locate expression in core le. Additional Printing Commands Table 9.
Format Summary Table 10. Format Summary Command 30 ADB Tutorial Description a Value of dot in symbolic form. b One byte in hexadecimal. B One byte in octal. c One byte as a character. d Two bytes in decimal. D Four bytes in decimal. f Four bytes in single precision oating point. F Eight bytes in double precision oating point. i HP Precision Architecture instruction. o Two bytes in octal. O Four bytes in octal. n Print a newline. r Print a blank space.
Expression Summary An expression consists of an operator and an operand (or operands). An operand can consist of the following components. Expression Components Table 11. Expression Components Examples Component Decimal integer 0d256, 0t256 Octal integer 0277, 0o277 Hexadecimal integer 0xff, 0xC0 Symbols flag, main Variables
Monadic Operators Table 13.
Index A ADB command format, 1-3 commands, 1-4 command summary, 1-28 debugger, 1-1 features, 1-1 interactive requests, 1-3 invoking, 1-1 location of arguments, 1-9 syntax, 1-1 variables, 1-19 additional printing commands, 1-29 address, 1-3 numeric, 1-18 symbolic, 1-18 advanced breakpoint usage, 1-15 ASCII interpretation, 1-21 assignment to variables, 1-28 B breakpoints, 1-11 program control, 1-28 C calling the shell, 1-28 commands additional printing, 1-29 assignment to variables, 1-28 breakpoints and p
maps, 1-18 monadic operators, 1-32 N newline command, 1-6 O object le, 1-2 operators dyadic, 1-31 monadic, 1-32 P patching, 1-22 core le, 1-22 C program, 1-22 object le, 1-22 printing commands additional, 1-29 formatted, 1-29 procedure entry time, 1-27 processes running debugging, 1-25 process identi er, 1-2 R registers setting the value, 1-20 requests, 1-3 locate and write, 1-22 running processes debugging, 1-25 Index-2 S setting breakpoints, 1-11 request, 1-12 shell calling, 1-28 stack-frame co