[ Previous | Next | Contents | Glossary | Home | Search ]
AIX Version 4.3 General Programming Concepts: Writing and Debugging Programs

Displaying and Manipulating the Source File with the adb Program

The following sections describe how you can use the adb program to display and manipulate the source file.

Displaying Instructions and Data

The adb program provides several subcommands for displaying the instructions and data of a given program and the data of a given data file. The subcommands and their formats are:

Display address Address [, Count ] = Format
Display instruction Address [, Count ] ? Format
Display value of variable Address [, Count ] / Format

In this format, the symbols and variables have the following meaning:

Address Gives the location of the instruction or data item.
Count Gives the number of items to be displayed.
Format Defines how to display the items.
= Displays the address of an item.
? Displays the instructions in a text segment.
/ Displays the value of variables.

Forming Addresses

In the adb program addresses are 32-bit values that indicate a specific memory address. They can, however, be represented in the following forms:

Absolute address The 32-bit value is represented by an 8-digit hexadecimal number, or its equivalent in one of the other number-base systems.
Symbol name The location of a symbol defined in the program can be represented by the name of that symbol in the program.
Entry points The entry point to a routine is represented by the name of the routine preceded by a . (period). For example, to refer to the address of the start of the main routine, use the following notation:
.main
Displacements You can refer to other points in the program by using displacements from entry points in the program. For example, the following notation references the instruction that is 4 bytes past the entry point for the symbol main :
.main+4

Displaying an Address

Use the = (equal sign) subcommand to display an address in a given format. This command displays instruction and data addresses in a simpler form and can display the results of arithmetic expressions. For example, entering:

main=an

displays the address of the symbol main :

10000370:

The following example shows a command that displays (in decimal) the sum of the internal variable b and the hexadecimal value 0x2000, together with its output:

<b+0x2000=D
    268443648

If a count is given, the same value is repeated that number of times. The following example shows a command that displays the value of main twice and the output that it produces:

main,2=x
    370 370

If no address is given, the current address is used. After running the above command once (setting the current address to main ), the following command repeats that function:

,2=x
    370 370

If you do not specify a format, the adb debug program uses the last format that was used with this command. For example, in the following sequence of commands, both main and one are displayed in hexadecimal:

main=x
  370
one=
  33c

Displaying the C Stack Backtrace

To trace the path of all active functions, use the $c subcommand. This subcommand lists the names of all functions that have been called and have not yet returned control. It also lists the address from which each function was called and the arguments passed to each function. For example, the following command sequence sets a breakpoint at the function address .f+2 in the adbsamp2 program. The breakpoint calls the $c subcommand. The program is started, runs to the breakpoint, and then displays a backtrace of the called C language functions:

.f+2:b$c
:r
adbsamp2:running
.f(0,0) .main+26
.main(0,0,0) start+fa
breakpoint                f+2:           tgte     r2,r2

By default, the $c subcommand displays all calls. To display fewer calls, supply a count of the number of calls to display. For example, the following command displays only one of the active functions at the preceding breakpoint:

,1$c
.f(0,0) .main+26

Choosing Data Formats

A format is a letter or character that defines how data is to be displayed. The following are the most commonly used formats:

Letter Format
a The current symbolic address
b One byte in octal (displays data associated with instructions, or the high or low byte of a register)
c One byte as a character (char variables)
d Halfword in decimal (short variables)
D Fullword in decimal (long variables)
i Machine instructions in mnemonic format
n A new line
o Halfword in octal (short variables)
O Fullword in octal (long variables)
r A blank space
s A null-terminated character string (null-terminated arrays of char variables)
t A horizontal tab
u Halfword as an unsigned integer (short variables)
x Halfword in hexadecimal (short variables)
X Fullword in hexadecimal (long variables)

For example, the following commands produce the indicated output when using the adbsamp example program:

Command Response
main=o 1560
main=O 4000001560
main=d 880
main=D 536871792
main=x 370
main=X 20000370
main=u 880

A format can be used by itself or combined with other formats to present a combination of data in different forms. You can combine the a, n, r, and t formats with other formats to make the display more readable.

Changing the Memory Map

You can change the values of a memory map by using the ?m and /m subcommands. These commands assign specified values to the corresponding map entries. The commands have the form:

[,count] ?m b1 e1 f1
[,count] /m b1 e1 f2

The following example shows the results of these commands on the memory map displayed with the $m subcommand in the previous example:

,0?m    10000100         10000470       0
/m      100      100     100
$m
  [0] :   ?map :   'adbsamp3'
 b1 = 0x10000100,  e1 = 10000470,  f1 = 0
 b2 = 0x20000600,  e2 = 0x2002c8a4, f2 = 0x600
 
 [1] :  ?map :   'shr.o' in library '/usr/ccs/lib/libc.a'
 b1 = 0xd00d6200,  e1 = 0xd01397bf,  f1 = 0xd00defbc
 b2 = 0x20000600,  e2 = 0x2002beb8, f2 = 0x4a36c
  
  [-] : /map :  '-'
 b1 = 100,    e1 = 100,   f1 = 100
 b2 = 0,    e2 = 0,     f2 = 0

To change the data segment values, add an * (asterisk) after the / or ?.

,0?*m   20000270         20000374       270
/*m     200      200     200
$m
  [0] : ?map :   'adbsamp3'
 b1 = 0x10000100,  e1 = 10000470,  f1 = 0
 b2 = 0x20000270,  e2 = 0x20000374, f2 = 0x270
 
 [1] :  ?map :   'shr.o' in library '/usr/ccs/lib/libc.a'
 b1 = 0xd00d6200,  e1 = 0xd01397bf,  f1 = 0xd00defbc
 b2 = 0x20000600,  e2 = 0x2002beb8, f2 = 0x4a36c
 
  [-] :  /map :  '-'
 b1 = 100,    e1 = 100,   f1 = 100
 b2 = 0,    e2 = 0,     f2 = 0

Patching Binary Files

You can make corrections or changes to any file, including executable binary files, by starting the adb program with the -w flag and by using the w and W subcommands.

Locating Values in a File

Locate specific values in a file by using the l and L subcommands. The subcommands have the form:

?l Value

OR

/l Value

The search starts at the current address and looks for the expression indicated by Value. The l subcommand searches for 2-byte values. The L subcommand searches for 4-byte values.

The ?l subcommand starts the search at the current address and continues until the first match or the end of the file. If the value is found, the current address is set to that value's address. For example, the following command searches for the first occurrence of the f symbol in the adbsamp2 file:

?l .f.
write+a2

The value is found at .write+a2 and the current address is set to that address.

Writing to a File

Write to a file by using the w and W subcommands. The subcommands have the form:

[ Address ] ?w Value

In this format, the Address parameter is the address of the value you want to change, and the Value parameter is the new value. The w subcommand writes 2-byte values. The W subcommand writes 4-byte values. For example, the following commands change the word "This" to "The":

?l .Th.
?W .The.

The W subcommand changes all four characters.

Making Changes to Memory

Make changes to memory whenever a program has run. If you have used an :r subcommand with a breakpoint to start program operation, subsequent w subcommands cause the adb program to write to the program in memory rather than to the file. This command is used to make changes to a program's data as it runs, such as temporarily changing the value of program flags or variables.

Using adb Variables

The adb debug program automatically creates a set of its own variables when it starts. These variables are set to the addresses and sizes of various parts of the program file as defined in the following table:

Variable Content
0 Last value printed
1 Last displacement part of an instruction source
2 Previous value of the 1 variable
9 Count on the last $< or $<< command
b Base address of the data segment
d Size of the data segment
e Entry address of the program
m "Magic" number
s Size of the stack segment
t Size of the text segment

The adb debug program reads the program file to find the values for these variables. If the file does not seem to be a program file, then the adb program leaves the values undefined.

To display the values that the adb debug program assigns to these variables, use the $v subcommand. This subcommand lists the variable names followed by their values in the current format. The subcommand displays any variable whose value is not 0 (zero). If a variable also has a non-zero segment value, the variable's value is displayed as an address. Otherwise, it is displayed as a number. The following example shows the use of this command to display the variable values for the sample program adbsamp:

$v
Variables
0 = undefined
1 = undefined
2 = undefined
9 = undefined
b = 10000000
d = 130
e = 10000038
m = 108
t = 298

Specify the current value of an adb variable in an expression by preceding the variable name with < (less than sign). The following example displays the current value of the b base variable:

<b=X
10000000

Create your own variables or change the value of an existing variable by assigning a value to a variable name with > (greater than sign). The assignment has the form:

Expression > VariableName

where the Expression parameter is the value to be assigned to the variable and the VariableName parameter is the variable to receive the value. The VariableName parameter must be a single letter. For example, the assignment:

0x2000>b

assigns the hexadecimal value 0x2000 to the b variable. Display the contents of b again to show that the assignment occurred:

<b=X
 2000

Finding the Current Address

The adb program has two special variables that keep track of the last address used in a command and the last address typed with a command. The . (period) variable, also called the current address, contains the last address used in a command. The " (double quotation mark) variable contains the last address typed with a command. The . and " variables usually contain the same address except when implied commands, such as the newline and ^ (caret) characters, are used. These characters automatically increase and decrease the . variable but leave the ) (right parenthesis) variable unchanged.

Both the . and the " variables can be used in any expression. The < (less than sign) is not required. For example, the following commands display these variables at the start of debugging with the adbsamp program:

.=
    0.
=
    0

Displaying External Variables

Use the $e subcommand to display the values of all external variables in the adb program. External variables are the variables in your program that have global scope or have been defined outside of any function, and include variables defined in library routines used by your program, as well as all external variables of shared libraries.

The $e subcommand is useful to get a list of the names for all available variables or a summary of their values. The command displays one name on each line with the variable's value (if any) on the same line. If the Count parameter is specified, only the external variables associated with that file are printed.

The following example illustrates the setting of a breakpoint in the adbsamp2 sample program that calls the $e subcommand, and the output that results when the program runs (be sure to delete any previous breakpoints that you may have set):

.f+2:b,0$e
:r
adbsamp2: running
_errno: 0
_environ:  3fffe6bc
__NLinit:  10000238
_main: 100001ea
_exit: 1000028c
_fcnt: 0
_loop_count:  1
_f:   100001b4
_NLgetfile: 10000280
_write: 100002e0
__NLinit__X:  10000238
_NLgetfile__X:   10000280
__cleanup: 100002bc
__exit: 100002c8
_exit__X:  1000028c
__cleanup__X:  100002bc
breakpoint .f+2:  st r2,1c(r1)

Displaying the Address Maps

The adb program prepares a set of maps for the text and data segments in your program and uses these maps to access items that you request for display. Use the $m subcommand to display the contents of the address maps. The subcommand displays the maps for all segments in the program and uses information taken from either the program and core files or directly from memory.

The $m subcommand displays information similar to the following:

$m
  [0] : ?map :   'adbsamp3'
  b1 = 0x10000200,  e1 = 0x10001839,  f1 = 0x10000200
  b2 = 0x2002c604,  e2 = 0x2002c8a4,  f2 = 0x600
 
  [1] : ?map :   'shr.o' in library 'lib/libc.a'
  b1 = 0xd00d6200,  e1 = 0xd013976f,  f1 = 0xd00defbc
  b2 = 0x20000600,  e2 = 0x2002bcb8,  f2 = 0x4a36c
 
  [-] :  /map :          '-'
  b1 = 0x0000000,  e1 = 0x00000000,  f1 = 0x00000000
  b2 = 0x0000000,  e2 = 0x00000000,  f2 = 0x00000000

The display defines address-mapping parameters for the text (b1 , e1 , and f1 ) and data (b2e2 , and f2 ) segments for the two files being used by the adb debug program. This example shows values for the adbsamp3 sample program only. The second set of map values are for the core file being used. Since none was in use, the example shows the file name as - (dash).

The value displayed inside the square brackets can be used as the Count parameter in the ?e and ?m subcommands.

Related Information

adb Debug Program Overview.

Using adb Expressions.

adb Debug Program Expressions


[ Previous | Next | Contents | Glossary | Home | Search ]