The
dbx
debugger is a tool for source level debugging. The debugger can be
used with C,
Fortran,
Pascal,
assembly language, and machine code. After invoking
dbx
,
you can issue
dbx
commands that control and trace execution, display variable and
expression values, and display and edit source files. The
dbx
debugger is a command-line program.
The
ladebug
debugger, an alternate debugger,
provides both command-line and graphical user interfaces.
In addition to supporting some languages that are not supported by
dbx
,
the
ladebug
debugger also supports features for debugging multithreaded programs.
For more information about
ladebug
,
see the
Ladebug Debugger Manual.
This chapter provides information on the following topics:
dbx
debugger
dbx
commands
dbx
and enter
dbx
commands using options provided by the
dbx
monitor
Examples in this chapter refer to a sample program called
sam
.
The C language source program
(sam.c
)
is listed in
Example 5-1.
In addition to the conventions outlined in the preface of this manual, an additional convention is used in the command descriptions in this chapter; certain words in uppercase indicate variables for which specific rules apply. These words are described in Table 5-1.
Keyword | Value |
ADDRESS
|
Any expression specifying a machine address. |
COMMAND_LIST
|
One or more commands, each separated by semicolons. |
DIR
|
Directory name. |
EXP
|
Any expression including program variable names for the command.
Expressions can contain
dbx
variables, for example,
($listwindow
+
2) .
If you want to use the variable names
in ,
to ,
or
at
in an expression, you must surround them with parentheses; otherwise,
dbx
assumes that these words are debugger keywords.
|
FILE
|
File name. |
INT
|
Integer value. |
LINE
|
Source code line number. |
NAME
|
Name of a
dbx
command.
|
PROCEDURE
|
Procedure name or an activation level on the stack. |
REGEXP
|
Regular expression string. See
ed (1).
|
SIGNAL
|
System signal. See
signal (2).
|
STRING
|
Any ASCII string. |
VAR
|
Valid program variable or
dbx
predefined variable (see
Table 5-9).
For machine-level debugging,
VAR
can also be an address. You must qualify program variables with
duplicate names as described in Section 5.3.2.
|
The following example illustrates the use of the uppercase words in
commands:
(dbx)
stop VAR in PROCEDURE if EXP
Enter
stop
,
in
,
and
if
as shown. Enter the values for
VAR
,
PROCEDURE
,
and
EXP
as defined in
Table 5-1.
Note
Information on debugging multiple asynchronous processes, including extensions to the syntax of certain
dbx
commands to provide control of the asynchronous session, is contained in Section 5.12.
The following sections introduce the debugger and some debugging concepts. They also give suggestions about how to approach a debugging session, including where to start, how to isolate errors, and how to avoid common pitfalls. If you are an experienced programmer, you might not need to read these sections.
The
dbx
debugger enables you to trace problems in a program object at the
source code level or at the machine code level. With
dbx
,
you control a program's execution, monitoring program control flow,
variables, and memory locations. You can also use
dbx
to trace the logic and flow of control to become familiar with a
program written by someone else.
Activation levels define the currently active scopes (usually
procedures) on the stack. An activation stack is a list of calls that
starts with the initial program, usually
main()
.
The most recently called procedure or block is number 0. The next
procedure called is number 1. The last activation level is always the
main procedure (the procedure that controls the whole program).
Activation levels can also consist of blocks that define local
variables within procedures. You see activation levels in stack traces
(see the
where
and
tstack
debugger commands) and when moving around the activation stack (see the
up
,
down
,
and
func
debugger commands). The following example shows a stack trace produced
by a
where
command:
> 0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04] [1] 1 main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac] [2] | | | | | | [3][4] [5] [6] [7] [8]
prnt
.
The activation level of
prnt
is 0; this function is at the top of the stack.
[Return to example]
main
.
[Return to example]
>
)
indicates the activation level that is currently under examination.
[Return to example]
Because the
dbx
debugger finds only run-time errors, you should fix compiler errors
before starting a debugging session. Run-time errors can cause a
program to fail during execution (resulting in the creation of a core
dump file) or to produce incorrect results. The approach for debugging
a program that fails during execution differs from the approach for
debugging a program that executes to completion but produces incorrect
results. (See
Section 5.1.4
for information on how to debug programs that produce incorrect
results.)
If a program fails during execution, you can usually save time by using the following approach to start a debugging session instead of blindly debugging line by line:
dbx
,
specifying any appropriate flags and the names of the
executable file and the core dump file on the
dbx
command line.
where
command to locate the point of failure.
Note
If you have not stripped symbol table information from the object file, you can get a stack trace even if the program was not compiled with the
-g
debug flag.
stop
or
stopi
commands.
print
command to see where a variable might have been assigned an incorrect
value.
If you still cannot find the error, other
dbx
commands described in this chapter might be useful.
If a program executes to completion but produces incorrect values or output, take the following steps:
where
command.
print
command.
The debugger cannot solve all problems. For example, if your program's logic is incorrect, the debugger can only help you find the problem, not solve it. When information displayed by the debugger appears confusing or incorrect, taking the following actions might correct the situation:
if
conditions). The debugger might not recognize a source statement
written with several others on the same line.
Similarly,
dbx
will not reflect changes you make if you edit and recompile your
program in one window on a workstation while running the debugger in
another window. You must stop and restart
dbx
each time you want it to recognize changes you have made.
dbx
keyword, you must enclose the expression within parentheses. For
example, in order to display the value of
output
(a keyword in the
playback
and
record
commands, discussed in
Section 5.9.4),
you must specify the following command:
(dbx)
print (output)
-g
flag.
Before invoking
dbx
,
you need to compile the program for debugging. You might also want to
create a
dbx
initialization file that will execute commands when the debugger is
started.
To use the debugger, specify the
-g
flag at compilation time. With this flag set, the compiler inserts
into the program symbol table information that the debugger uses to
locate variables. With the
-g
flag set, the compiler also sets its optimization level to
-O0
.
When you use different levels of optimizing, for example
-O2
,
the optimizer does not alter the flow of control within a program, but
it might move operations around so that the object code and source code
do not correspond. These changed sequences of code can create
confusion when you use the debugger.
You can do limited debugging on code compiled without the
-g
flag. For example, the following commands work properly without
recompiling for debugging:
stop
in
PROCEDURE
stepi
cont
conti
(ADDRESS)/<COUNT><MODE>
tracei
Although you can do limited debugging, it is usually more useful to
recompile the program with
-g
.
Note that the debugger does not warn you if an object file was
compiled without the
-g
flag.
Complete symbol table information is available only for programs
in which all modules have been compiled with the
-g
flag. Other programs will have symbol table information only for
symbols that are either referenced by or defined in modules compiled
with the
-g
flag.
Note
Any routines in shared library applications in which breakpoints are to be set must be compiled with the
-g
flag. If the-g
flag is not specified, the symbol table information thatdbx
needs to set breakpoints is not generated anddbx
will not be able to stop the application.
You can create a
dbx
initialization file that contains commands you normally issue at
the beginning of each
dbx
session. For example, the file could contain the following commands:
set $page = 5 set $lines = 20 set $prompt = "DBX> " alias du dump
The initialization file must have the name
.dbxinit
.
Each time you invoke the debugger,
dbx
executes the commands in
.dbxinit
.
The debugger looks first for
.dbxinit
in the current directory and then in your home directory (the directory
assigned to the
$HOME
environment variable).
You invoke
dbx
from the shell command line by entering
dbx
and the optional parameters.
After invocation,
dbx
sets the current function to the first procedure of the program.
The
dbx
command has the following syntax:
dbx
[
flags
]
[
objfile
[
corefile
]
]
flags
dbx
command line are shown in
Table 5-2.
objfile
objfile
is not specified,
dbx
uses
a.out
by default.
corefile
corefile
,
dbx
lists the point of program failure. The dump file holds an image of
memory at the time the program failed. Use
dbx
commands to get a stack trace and look at the core file code. The
debugger displays information from the core file, not from memory as it
usually does.
The maximum number of arguments accepted by
dbx
is 1000; however, system limits on your machine might reduce this
number.
Flag | Function |
-cfilename
|
Selects an initialization command file other than your
.dbxinit
file.
|
-Idirname
|
Tells
dbx
to look in the specified directory for source files. To specify
multiple directories, use a separate
-I
for each. Unless you specify this flag when you invoke
dbx ,
the debugger looks for source files in the current directory and in the
object file's directory. You can change directories with the
use
command (see Section 4.6.1).
|
-i
|
Invokes
dbx
in interactive mode. With this flag set,
dbx
does not treat source lines beginning with number signs
(# )
as
comments.
|
-k
|
Maps memory addresses. This flag is useful for kernel debugging.
(For information on kernel debugging, see
krash (8)
and the manual
Kernel Debugging.)
|
-pid process-id
|
Attaches
dbx
to a currently running process.
|
-r
|
Immediately executes the object file that you specify on the command
line. If program execution terminates with an error,
dbx
displays the message that describes the error. You can then either
invoke the debugger or allow the program to continue exiting. The
dbx
debugger reads from
/dev/tty
when you specify the
-r
flag and standard input is not a terminal. If the program executes
successfully,
dbx
prompts you for input.
|
The following example invokes
dbx
with no flags. Because an object file name is not specified,
dbx
prompts for one. In this case, the user responds with
sam
.
The default debugger prompt is
(dbx)
.
%
dbx
enter object file name (default is 'a.out'):
sam
dbx version 3.12 Type 'help' for help.
main: 23 if (argc < 2) { (dbx)
Use the
quit
or
q
command to end a debugging session. The
quit
command accepts no arguments.
You can enter up to 10,240 characters on an input line. Long lines can
be continued with a backslash
(\
).
If a line exceeds 10,240 characters,
dbx
displays an error message. The maximum string length is also 10,240.
The following sections describe scoping and the use of qualified
variable names,
dbx
expressions and precedence, and
dbx
data types and constants.
Variables in
dbx
are qualified by file, procedure, block, or structure.
When using commands like
print
to display a variable's value,
dbx
indicates the scope of the variable when the scope could
be ambiguous (for example, you have a variable
by the same name in two or more procedures). If the scope
is wrong, you can specify the full scope of the variable by
separating scopes with periods. For example:
sam.main.i | | | [1][2] [3]
The
dbx
debugger recognizes expression operators from C; these operators can
also be used for debugging any other supported language. (Note that
dbx
uses brackets
([ ]
)
for array subscripts even in Fortran, whose natural subscript
delimiters are parentheses.) In addition to the standard C operators,
dbx
uses the number sign
(#
)
as shown in
Table 5-3.
Syntax | Description |
("FILE"
#EXP)
|
Uses the line number specified by
#EXP
in the file named by
FILE .
|
(PROCEDURE
#EXP)
|
Uses the relative line number specified by
#EXP
in the procedure named by
PROCEDURE .
|
(#EXP)
|
Returns the address for the line specified by
(#EXP) .
|
Operators follow the C language precedence.
Table 5-4
shows the language operators recognized by
dbx
in order of precedence from top to bottom and from left to right, with
the
dbx
-specific
number-sign operator included among the unary operators to show its
place in the precedence hierarchy.
Unary: |
& ,
+ ,
- ,
*
(pointer),
# ,
sizeof() ~ ,
/ ,
(type) ,
(type *)
|
Binary: |
<< ,
>> ,
" ,
! ,
== ,
!= ,
<= ,
>= ,
< ,
> ,
& ,
&& ,
| ,
|| ,
+ ,
- ,
* ,
/ % ,
[] ,
->
|
Table Notes:
sizeof
operator specifies the number of bytes retrieved to get an element, not
(number-of-bits
+7)/8
.
dbx
also accepts two slashes
(//
)
as a division operator.
Table 5-5
lists the built-in data types that
dbx
commands can use.
Data Type | Description | Data Type | Description | |
$address
|
Pointer |
$real
|
Double precision real | |
$boolean
|
Boolean |
$short
|
16-bit integer | |
$char
|
Character |
$signed
|
Signed integer | |
$double
|
Double precision real |
$uchar
|
Unsigned character | |
$float
|
Single precision real |
$unsigned
|
Unsigned integer | |
$integer
|
Signed integer |
$void
|
Empty |
You can use the built-in data types for type coercion -- for example,
to display the value of a variable in a type other than the type
specified in the variable's declaration. The
dbx
debugger understands C language data types, so that you can refer to
data types without the
$
.
The types of constants that are acceptable as input to
dbx
are shown in
Table 5-6.
Constants that are output from
dbx
are displayed by default as decimal values.
Constant | Description |
false
|
0 |
true
|
Nonzero |
nil
|
0 |
0xnumber
|
Hexadecimal |
0tnumber
|
Decimal |
0number
|
Octal |
number
|
Decimal |
number.[ number][e|E][+|-]EXP
|
Float |
Notes:
$octin
variable changes the default input expected to octal. The
$hexin
variable changes the default input expected to hexadecimal (see
Section 5.5.2).
$octints
variable changes the default output to octal. The
$hexints
variable changes the default output to hexadecimal (see
Section 5.5.2).
The
dbx
debugger provides a command history, command-line editing, and symbol
name completion. The
dbx
debugger also allows multiple commands on an input line. These
features can reduce the amount of input required or allow you to repeat
previously executed commands.
The debugger keeps a command history that allows you to repeat
debugger commands without retyping them. You can display these
commands by using the
history
command. The
$lines
variable controls the number of history lines saved. The default is 20
commands. You can use the
set
command to modify the
$lines
variable (see
Section 5.5.1).
To repeat a command, use the Return key or one of the exclamation point
(!
)
commands.
The
history
command has the following forms:
history
$repeatmode
variable to 0 (see
Section 5.5.1).
!string
!integer
!-integer
integer
)
before the most recent command.
The following example displays the history list and then repeats
execution of the twelfth command in the list:
(dbx)
history
10 print x 11 print y 12 print z
(dbx)
!12
(!12 = print z) 123 (dbx)
The
dbx
debugger provides support for command line editing. You can edit a
command line to correct mistakes without reentering the entire command.
To enable command-line editing, set the
EDITOR
,
EDITMODE
,
or
LINEEDIT
environment variable before you invoke
dbx
.
For example, to set
LINEEDIT
from the C shell, you would enter the following command:
%
setenv LINEEDIT
From the Bourne or Korn shells, you would enter this command:
$
export LINEEDIT
The debugger offers the following modes of command line editing:
LINEEDIT
is not set and either of the environment variables
EDITMODE
or
EDITOR
contains a path ending in
vi
,
the debugger uses a command line editing mode that resembles the Korn
shell's
vi
mode, in which the following editing keys are recognized:
$ + - 0 A B C D E F I R S W X ^ a b c d e f h i j k l r s w x ~ Ctrl/D Ctrl/H Ctrl/J Ctrl/L Ctrl/M Ctrl/V
See
ksh
(1)
for more information.
LINEEDIT
is set to any value, even the null string, or if
LINEEDIT
is not set and either of the environment variables
EDITMODE
or
EDITOR
contains a path ending in
emacs
,
the debugger uses a command line editing mode that resembles the Korn
shell's
emacs
mode. This mode behaves slightly differently depending on whether it
is enabled by
LINEEDIT
or by
EDITOR
or
EDITMODE
.
Table 5-7
lists the
emacs
-mode
command line editing commands.
Command | Function |
Ctrl/A | Moves the cursor to the beginning of the command line. |
Ctrl/B | Moves the cursor back one character. |
Ctrl/C | Clears the line. |
Ctrl/D | Deletes the character at the cursor. |
Ctrl/E | Moves the cursor to the end of the line. |
Ctrl/F | Moves the cursor ahead one character. |
Ctrl/H | Deletes the character immediately preceding the cursor. |
Ctrl/J | Executes the line. |
Ctrl/K |
(When enabled by
EDITOR
or
EDITMODE )
Deletes from the cursor to the end of the line. If preceded by a
numerical parameter whose value is less than the current cursor
position, deletes from given position up to the cursor. If
preceded by a numerical parameter whose value is greater than the
current cursor position, deletes from cursor up to given position.
|
Ctrl/K char
|
(When enabled by
LINEEDIT )
Deletes characters until the cursor rests on the next occurrence of
char .
|
Ctrl/L | Redisplays the current line. |
Ctrl/M | Executes the line. |
Ctrl/N | Moves to the next line in the history list. |
Ctrl/P | Moves to the previous line in the history list. |
Ctrl/R char
|
Searches back in the current line for the specified character. |
Ctrl/T | Interchanges the two characters immediately preceding the cursor. |
Ctrl/U | Repeats the next character four times. |
Ctrl/W | Deletes the entire line. |
Ctrl/Y | Inserts immediately before the cursor any text cut with Ctrl/K. |
Ctrl/Z | Tries to complete a file or symbol name. |
Escape | Tries to complete a file or symbol name. |
Down Arrow | Moves to the next line in the history list. |
Up Arrow | Moves to the previous line in the history list. |
Left Arrow | Moves the cursor back one character. |
Right Arrow | Moves the cursor ahead one character. |
You can enter multiple commands on the command line by using a
semicolon
(;
)
as a separator. This feature is useful when you are using
the
when
command (see
Section 5.8.4).
The following example has two commands on one command line; the first
command stops the program and the second command reruns it:
(dbx)
stop at 40; rerun
[2] stop at "sam.c":40 [2] stopped at [main:40 ,0x120000b40] i=strlen(line1.string); (dbx)
The
dbx
debugger provides symbol name completion. When you enter a partial
symbol name and press Ctrl/Z,
dbx
attempts to complete the name. If a unique completion is found,
dbx
redisplays the input with the unique completion added; otherwise, all
possible completions are shown, and you can choose one.
To enable symbol name completion, you must enable command line editing
as described in
Section 5.4.2.
The following example displays all names beginning with the
letter "i":
(dbx)
i
[Ctrl/Z]
ioctl.ioctl .ioctl isatty.isatty .isatty i int [1]
(dbx) i [2]
dbx
prompts again with the previously specified string, giving you an
opportunity to specify additional characters and repeat the search.
[Return to example]
The following example shows symbol name completion. In this case, the
entry supplied is unambiguous:
(dbx)
print file
[Ctrl/Z]
(dbx) print file_header_ptr 0x124ac (dbx)
The
dbx
debugger provides commands for setting and removing
dbx
variables, creating and removing aliases, invoking a subshell, checking
and deleting items from the status list, displaying a list of object
files associated with an application, and recording and playing back
input.
The
set
command defines a
dbx
variable, sets an existing
dbx
variable to a different value, or displays a list of existing
dbx
predefined variables. The
unset
command removes a
dbx
variable. Use the
print
command to display the values of program and debugger variables. The
dbx
predefined variables are listed in
Table 5-8.
You cannot define a debugger variable with the same name as a program
variable.
The
set
and
unset
commands have the following forms:
set
dbx
predefined variables.
set
VAR
=
EXP
unset
VAR
dbx
variable.
The following example illustrates the
set
and
unset
commands:
(dbx)
set [1]
$listwindow 10 $datacache 1 $main "main" $pagewindow 22 test 5 $page 1 $maxstrlen 128 $cursrcline 24
more (n if no)?
n
(dbx)
set test = 12 [2]
.nr C# 1
(dbx)
set
$listwindow 10 $datacache 1 $main "main" $pagewindow 22 test 12 $page 1 $maxstrlen 128 $cursrcline 24
more (n if no)?
n
.nr C# 3
(dbx)
unset test [3]
.nr C# 1
(dbx)
set
$listwindow 10 $datacache 1 $main "main" $pagewindow 22 $page 1 $maxstrlen 128 $cursrcline 24
more (n if no)?
n
(dbx)
dbx
predefined variables.
[Return to example]
The predefined
dbx
variables are shown in
Table 5-8.
Each variable is labeled I for integer, B for boolean, or S for string.
Variables that you can examine but cannot modify are indicated by an R.
Type | Name | Default | Description |
S |
$addrfmt
|
0x%lx
|
Specifies the format for addresses. Can be set to anything you can
format with a C language
printf
statement.
|
B |
$assignverify
|
1 | Specifies whether new values are displayed when assigning a value to a variable. |
B |
$asynch_interface
|
0 |
Controls whether
dbx
is, or can be, configured to control multiple asynchronous processes.
Incremented by 1 when a process is attached; decremented by 1 when a
process terminates or is detached. Can also be set by user. If 0 or
negative, asynchronous debugging is disabled.
|
B |
$break_during_step
|
0 |
Controls whether breakpoints are checked while processing
step/stepi ,
next/nexti ,
call ,
return ,
and so on.
|
B |
$casesense
|
0 | Specifies whether source searching and variables are case sensitive. A nonzero value means case sensitive; a 0 means not case sensitive. |
I R |
$curevent
|
0 |
Shows the last event number as reported by the
status
command.
|
I R |
$curline
|
0 | Shows the current line in the source code. |
I R |
$curpc
|
- |
Shows the current address. Used with the
wi
and
li
aliases.
|
I R |
$cursrcline
|
1 | Shows the last line listed plus 1. |
B |
$datacache
|
1 |
Caches information from the data space so that
dbx
only has to check the data space once.
If you are debugging the operating system, set this
variable to 0; otherwise, set it to a nonzero value.
|
S R |
$defaultin
|
Null string |
Shows the name of the file that
dbx
uses to store information when using the
record
input
command.
|
S R |
$defaultout
|
Null string |
Shows the name of the file that
dbx
uses to store information when using the
record
output
command.
|
B |
$dispix
|
0 |
When set to 1, specifies display of only real instructions when
debugging in
pixie
mode.
|
B |
$hexchars
|
Not defined | A nonzero value indicates that character values are shown in hexadecimal. |
B |
$hexin
|
Not defined | A nonzero value indicates that input constants are hexadecimal. |
B |
$hexints
|
Not defined | A nonzero value indicates that output constants are shown in hexadecimal; a nonzero value overrides octal. |
B |
$hexstrings
|
Not defined | A nonzero value indicates that strings are displayed in hexadecimal; otherwise, strings are shown as characters. |
I R |
$historyevent
|
None | Shows the current history number. |
I |
$lines
|
20 |
Specifies the size of the
dbx
history list.
|
I |
$listwindow
|
$pagewindow/2
|
Specifies the number of lines shown by the
list
command.
|
S |
$main
|
main
|
Specifies the name of the procedure where execution begins. The
debugger starts the program at
main()
unless otherwise specified.
|
I |
$maxstrlen
|
128 |
Specifies the maximum number of characters in strings that
dbx
prints for pointers to strings.
|
B |
$octin
|
Not defined | Changes the default input constants to octal when set to a nonzero value. Hexadecimal overrides octal. |
B |
$octints
|
Not defined | Changes the default output constants to octal when set to a nonzero value. Hexadecimal overrides octal. |
B |
$page
|
1 | Specifies whether to page long information. A nonzero value enables paging; a zero disables it. |
I |
$pagewindow
|
Various | Specifies the number of lines displayed when viewing information that is longer than one screen. This variable should be set to the number of lines on the terminal. A value of 0 indicates a minimum of 1 line. The default value depends on the terminal type; for a standard video display, the default is 24. |
B |
$pimode
|
0 |
Displays input when using the
playback
input
command.
|
I |
$printdata
|
0 | A nonzero value indicates that the values of registers are displayed when instructions are disassembled; otherwise, register values are not displayed. |
B |
$printtargets
|
1 | If set to 1, specifies that displayed disassembly listings are to include the labels of targets for jump instructions. If set to 0, disables this label display. |
B |
$printwhilestep
|
0 |
For use with the
step
[n ]
and
stepi
[n ]
instructions. A nonzero value specifies that all
n
lines or instructions should be displayed. A zero value specifies
that only the last line or instruction should be displayed.
|
B |
$printwide
|
0 | Specifies wide (useful for structures or arrays) or vertical format for displaying variables. A nonzero value indicates wide format; zero indicates vertical format. |
S |
$prompt
|
dbx)
|
Sets the prompt for
dbx .
|
B |
$readtextfile
|
1 |
When set to a value of 1,
dbx
tries to read instructions from the object file instead of from the
process. This variable should always be set to 0 when the process
being debugged copies in code during the debugging process. However,
performance is better when
$readtextfile
is set to 1.
|
B |
$regstyle
|
1 |
Specifies the type of register names to be used. A value of 1 specifies
hardware names. A zero specifies software names as defined by the file
regdefs.h .
|
B | $repeatmode | 1 |
Specifies whether
dbx
should repeat the last command when the Return key is pressed.
A nonzero value indicates that the command is repeated; otherwise,
it is not repeated.
|
B | $rimode | 0 |
Records input when using the
record
output
command.
|
S | $sigvec |
sigaction
|
Tells
dbx
the name of the code called by the system to set signal handlers.
|
S | $sigtramp |
_sigtramp
|
Tells
dbx
the name of the code called by the system to invoke user signal
handlers.
|
B | $stop_all_forks | 0 |
Specifies whether
dbx
should stop every child process that is forked (1), or ignore many
of the forks generated by various system and library calls (0).
If
$stop_all_forks
is not set, the value of
$stop_on_fork
determines
dbx 's
behavior with forks.
$stop_all_forks
traps forks in libraries and system calls that are usually
ignored by
$stop_on_fork .
|
B | $stop_in_main | N/A |
Not used. This variable is displayed by the
set
command, but it presently has no effect on
dbx
operation.
|
B | $stop_on_exec | 1 |
Specifies whether
dbx
should detect calls to
execl(
)
and
execv(
) ,
and stop the newly activated images at the first line of
executable code.
|
B | $stop_on_fork | 1 |
Specifies whether
dbx
should advance a new image activated by a
fork(
)
or
vfork(
)
call to its main activation point and then stop (1) or continue until
stopped by a breakpoint or event (0). The
dbx
program tries to avoid stopping on forks from system or library
calls unless
$stop_all_forks
is set.
|
S | $tagfile |
tags
|
Contains a file name indicating the file in which the
tag
command and the
tagvalue
macro are to search for tags.
|
I | $traploops | 3 |
Specifies the number of consecutive calls to a
SIGTRAP
handler that will be made before
dbx
assumes that the program has fallen into a trap-handling loop.
|
The
alias
command defines a new alias or displays a list of all current aliases.
The
alias
command allows you to rename any debugger command. Enclose commands
containing spaces within double or single quotation marks. You can
also define a macro as part of an alias.
The
dbx
debugger has a group of predefined aliases. You can modify these
aliases or add new aliases. You can also include aliases in your
.dbxinit
file for use in future debugging sessions.
The
unalias
command removes an alias from a command. You must specify the alias to
remove. The alias is removed only for the current debugging session.
The
alias
and
unalias
commands have the following forms:
alias
alias
NAME1[(ARG1,...,ARGN)]
"NAME2"
NAME1
is the new name.
NAME2
is the command to string to rename.
ARG1,...,ARGN
are the command arguments.
unalias
NAME
NAME
is the alias name.
The following example illustrates the
alias
and
unalias
commands:
(dbx)
alias [1]
h history si stepi Si nexti
.
.
.
g goto s step
More (n if no) ?
n
(dbx)
alias ok(x) "stop at x" [2]
(dbx)
ok(52) [3]
[2] Stop at "sam.c":52 [4] (dbx)
(dbx)
unalias h [5]
(dbx)
alias
si stepi Si nexti
.
.
.
g goto s step
More (n if no)?
n
(dbx)
h
alias. (Notice that it disappears from the alias list.)
[Return to example]
Use the
status
command to check which, if any, of the following commands are currently
set:
stop
or
stopi
commands for breakpoints
trace
or
tracei
commands for line-by-line variable tracing
when
command
record
input
and
record
output
commands for saving information in a file
The
status
command accepts no arguments. For example:
(dbx)
status
[2] trace i in main [3] stop in prnt [4] record output /tmp/dbxt0018898 (0 lines)
(dbx)
The numbers in brackets (for example,
[2]
)
indicate status item numbers.
To delete breakpoints and stop the recording of input and output,
use the
delete
command. Deleting a breakpoint or stopping recording removes the
pertinent items from the status list produced by the
status
command. To disable breakpoints without deleting them, use the
disable
command. The
enable
command reenables disabled events.
The
delete
command has the following forms:
delete
EXP1[,...,EXPN]
delete
all
delete
*
The following example illustrates the use of the
delete
command:
(dbx)
status
[2] record output /tmp/dbxt0018898 (0 lines) [3] trace i in main [4] print pline at "sam.c": [5] stop in prnt
(dbx)
delete 4
(dbx)
status
[2] record output /tmp/dbxt0018898 (0 lines) [3] trace i in main [5] stop in prnt
(dbx)
The
disable
and
enable
commands have the following forms:
disable
EVENT1[,EVENT2,...]
enable
EVENT1[,EVENT2,...]
disable
all
enable
all
The
listobj
command displays the names of all the object files that have
been loaded by
dbx
,
together with their sizes and the address at which they were loaded.
These objects include the main program and all of the shared libraries
that are used in an application. The
listobj
command accepts no arguments. For example:
(dbx)
listobj
sam addr: 0x120000000 size: 0x2000 /usr/shlib/libc.so addr: 0x3ff80080000 size: 0xbc000
(dbx)
To invoke an interactive subshell at the
dbx
prompt, enter
sh
.
To return to
dbx
from a subshell, enter
exit
or press Ctrl/D. To invoke a subshell that performs a single command
and returns to
dbx
,
enter
sh
and the desired shell command. For example:
(dbx)
sh
%
date
Tue Aug 9 17:25:15 EDT 1994
%
exit
.
.
.
(dbx)
sh date
Tue Aug 9 17:29:34 EDT 1994
(dbx)
The following sections describe how to list and edit source code, change directories, change source files, search for strings in source code, display qualified symbol names, and display type declarations.
If you did not specify the
-I
flag when invoking
dbx
,
(see
Section 5.2.3),
the debugger looks for source files in the current directory or the
object file's directory. The
use
command has two functions:
The command recognizes absolute and relative pathnames (for example,
./
),
but it does not recognize the C-shell tilde
(~
).
The
use
command has the following forms:
use
use DIR1 ... DIRN
For example:
(dbx)
use
. [1]
(dbx)
use /usr/local/lib
(dbx)
use
/usr/local/lib [2]
(dbx)
As described in
Section 5.1.2,
the debugger maintains a stack of activation levels. To find the name
or activation number for a specific procedure, get a stack trace with
the
where
or
tstack
command. You can move through the activation stack by using the
up
,
down
,
and
func
commands.
The
where
command displays a stack trace showing the current activation levels
(active procedures) of the program being debugged. The
tstack
command displays a stack trace for all threads. See
Section 5.11
for more information about debugging threads.
The
where
and
tstack
commands have the following form:
where
[EXP]
tstack
[EXP]
If
EXP
is specified,
dbx
displays only the top
EXP
levels of the stack; otherwise, the entire stack is displayed.
If a breakpoint is set in
prnt
in the sample program
sam.c
,
the program runs and stops in the procedure
prnt()
.
If you enter
where
,
the debugger's stack trace provides the information shown in the
following example:
(dbx)
stop in prnt
[1] stop in prnt
(dbx)
run
.
.
.
(dbx)
where 1
> 0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04] | | | | | | [1][2] [3] [4] [5] [6]
(dbx)
pline
[Return to example]
The
up
and
down
commands move you directly up or down in the stack; they are useful
when tracking a call from one level to another. The
func
command can move you up or down incrementally or to a specific
activation level or procedure. The
func
command changes the current line, the current file, and the current
procedure, thus changing the scope of the variables you can access.
You can also use the
func
command to examine source code when a program is not executing.
The
up
,
down
,
and
func
commands have the following forms:
up
[EXP]
down
[EXP]
func
func
PROCEDURE
PROCEDURE
.
func
EXP
The following example illustrates these commands:
(dbx)
where
> 0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04] 1 main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac]
(dbx)
up
main: 45 prnt(&line1); [1]
(dbx)
where
0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04] > 1 main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac]
(dbx)
down
prnt: 52 fprintf(stdout,"%3d. (%3d) %s", [2]
(dbx)
where
> 0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04] 1 main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac]
(dbx)
func 1
main 47 prnt(&line1) [3]
(dbx)
main
.
[Return to example]
The
file
command displays the current source file name or changes the current
source file.
Note
Before setting a breakpoint or trace on a line number, use the
func
command to get the correct procedure. Thefile
command cannot be specific enough for the debugger to access the information necessary to set a breakpoint.
The
file
command has the following forms:
file
file
FILE
For example:
(dbx)
file
sam.c [1]
(dbx)
file data.c
(dbx)
file
data.c [2]
(dbx)
The
list
command displays lines of source code. The
dbx
variable
$listwindow
defines the number of lines that
dbx
lists by default. The
list
command uses the current file, procedure, and line unless
otherwise specified.
The
list
command has the following forms:
list
$listwindow
,
starting at the current line.
list
EXP
EXP
,
starting at the current line.
list
EXP1,EXP2
EXP1
to
EXP2
.
list
EXP:INT
EXP
),
lists the specified number of lines
(INT
),
overriding
$listwindow
.
list
PROCEDURE
$listwindow
lines.
The following example specifies a 2-line list starting at line 49:
(dbx)
list 49:2
49 void prnt(pline) 50 LINETYPE *pline;
If you use the
list
command's predefined alias
w
,
the output is as follows:
(dbx)
w
45 prnt(&line1); 46 } 47 } 48 49 void prnt(pline) > 50 LINETYPE *pline; 51 { * 52 fprintf(stdout,"%3d. (%3d) %s",pline->linenumber, 53 pline->length, pline->string); 54 fflush(stdout);
The right angle bracket in column 1
(>
)
indicates the current line, and the asterisk in column 2
(*
)
indicates the location of the program counter (pc) at this activation
level.
The slash
(/
)
and question mark
(?
)
commands search for regular expressions in source code. The slash
searches forward from the current line, and the question mark searches
backward. Both commands wrap around at the end of the file if
necessary, searching the entire file from the point of invocation back
to the same point. By default,
dbx
does not distinguish uppercase letters from lowercase when searching.
If you set the
dbx
variable
$casesense
to any nonzero value, the search is case sensitive.
The
/
and
?
commands have the following form:
/[REGEXP]
?[REGEXP]
(dbx)
/lines
no match
(dbx)
/line1
16 LINETYPE line1;
(dbx)
/
39 while(fgets(line1.string, sizeof(line1.string), fd) != NULL){ (dbx)
The
edit
command enables you to change source files from within
dbx
.
To make the changes effective, you must quit from
dbx
,
recompile the program, and restart
dbx
.
The
edit
command has the following forms:
edit
edit
FILE
The
edit
command loads the editor indicated by the environment variable
EDITOR
or, if
EDITOR
is not set, the
vi
editor. To return to
dbx
,
exit normally from the editor.
The
which
and
whereis
commands display program variables. These commands are useful for
debugging programs that have multiple variables with the same name
occurring in different scopes. The commands follow the rules described
in
Section 5.3.1.
The
which
and
whereis
commands have the following forms:
which
VAR
whereis
VAR
In the following example, the user checks to see where the default
variable named
i
is and then verifies that this is the only instance of
i
in the program by observing that
whereis
shows only the one occurrence.
(dbx)
which i
sam.main.i
(dbx)
whereis i
sam.main.i
The
whatis
command lists the type declaration for variables and procedures
in a program.
The
whatis
command has the following form:
whatis
VAR
For example:
(dbx)
whatis main
int main(argc,argv) int argc; unsigned char **argv;
(dbx)
whatis i
int i;
(dbx)
The following sections describe the
dbx
commands used to run a program,
step through source code, return from a procedure call, start at a
specified line, continue after stopping at a breakpoint, assign
values to program variables, patch an executable disk file,
execute a particular routine, set an environment variable, and
load shared libraries.
The
run
and
rerun
commands start program execution. Each command accepts program
arguments and passes those arguments to the program. If no arguments
are specified for a
run
command,
dbx
runs the program with no arguments. If no arguments are specified for
a
rerun
command,
dbx
defaults to the arguments used with the previous
run
or
rerun
command. You can specify arguments in advance of issuing a
rerun
command by using the
args
command. Arguments set by the
args
command are ignored by a subsequent
run
command.
You can also use these commands to redirect program input and output in a manner similar to redirection in the C shell:
<FILE1
redirects input to the program from the specified file.
>FILE2
redirects output from the program to the specified file.
>&FILE2
redirects both
stderr
and
stdout
to the specified file.
Note
The redirected output differs from the output saved with the
record
output
command (see Section 5.9.4.2), which saves debugger output, not program output.
The
run
,
args
,
and
rerun
commands have the following forms:
run
ARGN][ARG1
...
[<FILE1]
[>FILE2]
run
ARGN][ARG1
...
[<FILE1]
[>&FILE2]
args
ARGN][ARG1
...
[<FILE1]
[>FILE2]
args
ARGN][ARG1
...
[<FILE1]
[>&FILE2]
run
or
rerun
command.
rerun
ARGN][ARG1
...
[<FILE1]
[>FILE2]
rerun
ARGN][ARG1
...
[<FILE1]
[>&FILE2]
For example:
(dbx)
run sam.c [1]
0. (19)#include <stdio.h> 1. (14) struct line { 2. (19) char string[256];
.
.
.
Program terminated normally
(dbx)
rerun [2]
0. (19)#include <stdio.h> 1. (14) struct line { 2. (19) char string[256];
.
.
.
Program terminated normally
(dbx)
sam.c
.
[Return to example]
For debugging programs written in high-level languages, the
step
and
next
commands execute a fixed number of source code lines as specified by
EXP
.
For debugging programs written in assembly language, the
stepi
and
nexti
commands work the same as
step
and
next
except that they step by machine instructions instead of by program
lines. If
EXP
is not specified,
dbx
executes one source code line or machine instruction; otherwise,
dbx
executes the source code lines or machine instructions as follows:
dbx
debugger does not take comment lines into consideration in interpreting
EXP
.
The program executes
EXP
source code lines, regardless of the number of comment lines
interspersed among them.
step
and
stepi
,
dbx
considers
EXP
to apply both to the current procedure and to called procedures.
Program execution stops after
EXP
source lines in the current procedure and any called procedures.
next
and
nexti
,
dbx
considers
EXP
to apply only to the current procedure. Program execution stops after
executing
EXP
source lines in the current procedure, regardless of the number of
source lines executed in any called procedures.
The
step/stepi
and
next/nexti
commands have the following forms:
step
[EXP]
stepi
[EXP]
next
[EXP]
nexti
[EXP]
For example:
(dbx)
rerun
[7] stopped at [prnt:52,0x120000c04] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
step 2
0. ( 19) #include <stdio.h> [prnt:55 ,0x120000c48] }
(dbx)
step
[main:40 ,0x120000b40] i=strlen(line1.string);
(dbx)
The
$break_during_step
and
$printwhilestep
variables affect stepping. See
Table 5-8
for more information.
The
return
command is used in a called procedure to execute the remaining
instructions in the procedure and return to the calling procedure.
The
return
command has the following forms:
return
return
PROCEDURE
PROCEDURE
.
Stops ready to execute
the next sequential line in the named procedure.
For example:
(dbx)
rerun
[7] stopped at [prnt:52,0x120000c04] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
return
0. (19) #include <stdio.h> stopped at [main:45 +0xc,0x120000bb0] prnt(&line1); (dbx)
The
goto
command shifts to the specified line and continues execution. This
command is useful in a
when
statement -- for example, to skip a line known to cause problems. The
goto
command has the following form:
goto
LINE
For example:
(dbx)
when at 40 {goto 43}
[8] start sam.c:43 at "sam.c":40 (dbx)
For debugging programs written in high-level languages, the
cont
command resumes program execution after a breakpoint. For debugging
programs written in assembly language, the
conti
command works the same as
cont
.
The
cont
and
conti
commands have the following forms:
cont
conti
cont
to
LINE
conti
to
ADDRESS
cont
in
PROCEDURE
conti
in
PROCEDURE
cont
SIGNAL
conti
SIGNAL
cont
SIGNAL
to
LINE
conti
SIGNAL
to
ADDRESS
cont
SIGNAL
in
PROCEDURE
conti
SIGNAL
in
PROCEDURE
The following example shows the
cont
command in a C program:
(dbx)
stop in prnt
[9] stop in prnt
(dbx)
rerun
[9] stopped at [prnt:52,0x120000c04] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
cont
0. ( 19) #include <stdio.h> [9] stopped at [prnt:52,0x120000c04] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
The following example shows the
conti
command in an assembly-language program:
(dbx)
conti
0. ( 19) #include <stdio.h> [4] stopped at >*[prnt:52 ,0x120000c04] ldq r16,-32640(gp) (dbx)
The
assign
command changes the value of a program variable. The
assign
command has the following form:
assign
VAR
=
EXP
assign
EXP1
=
EXP2
VAR
or the address represented by the resolution of
EXP1
.
For example:
(dbx)
print i
19 [1]
(dbx)
assign i = 10
10 [2]
(dbx)
assign *(int *)0x444 = 1 [3]
1
(dbx)
The
patch
command patches an executable disk file to correct bad data or
instructions. Only text, initialized data, or read-only data areas can
be patched. The
bss
segment cannot be patched because it does not exist in disk files. The
patch
command fails if it is issued against a program that is executing.
The
patch
command has the following form:
patch
VAR
=
EXP
patch
EXP1
=
EXP2
VAR
or the address represented by the resolution of
EXP1
.
The patch is applied to the default disk file; you can use qualified
variable names to specify a patch to a file other than the default.
Applying a patch in this way also patches the in-memory image of the
file being patched.
For example:
(dbx)
patch &main = 0
(dbx)
patch var = 20
(dbx)
patch &var = 20
(dbx)
patch 0xnnnnn = 0xnnnnn
Although it is possible for you to set the current line pointer to
the beginning of a procedure, place a breakpoint at the end of the
procedure, and run the procedure, it is usually easier to use the
call
or
print
command to execute a procedure in your program. The
call
or
print
command executes the procedure you name on the command line. You can
pass parameters to the procedure by specifying them as arguments to the
call
or
print
command.
The
call
or
print
command does not alter the flow of your program. When the procedure
returns, the program remains stopped at the point where you issued the
call
or
print
command. The
print
command displays values returned by called procedures; the
call
command does not.
The
call
and
print
commands have the following forms:
call
PROCEDURE([parameters
])
print
PROCEDURE([parameters
])
For example:
(dbx)
stop in prnt [1]
[11] stop in prnt
(dbx)
call prnt(&line1) [2]
[11] stopped at [prnt:52,0x120000c] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
status [3]
[11] stop in prnt [12] stop at "sam.c":40 [2] record output example2 (126 lines)
(dbx)
delete 11,12 [4]
(dbx)
stop
command sets a breakpoint in the
prnt()
function.
[Return to example]
call
command begins executing the object code associated with
prnt()
.
The
line1
argument passes a string by reference to
prnt
.
[Return to example]
status
command displays the currently active breakpoints.
[Return to example]
delete
command deletes the breakpoints at lines 52 and 40.
[Return to example]
The
print
command allows you to include a procedure as part of an expression to
be printed. For example:
(dbx)
print sqrt(2.)+sqrt(3.)
Use the
setenv
command to set an environment variable. You can use this command to
set the value of an existing environment variable or create a new
environment variable. The environment variable is visible to both
dbx
and the program you are running under
dbx
control, but it is not visible after you exit the
dbx
environment; however, if you start a shell with the
sh
command within
dbx
,
that shell can see
dbx
environment variables. To change an environment variable for a
process, you must issue the
setenv
command before starting up the process within
dbx
with the
run
command.
The
setenv
command has the following form:
setenv
VAR
"STRING"
For example:
(dbx)
setenv TEXT "sam.c" [1]
(dbx)
run [2]
[4] stopped at [prnt:52,0x120000e34] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
setenv TEXT "" [3]
(dbx)
run [4]
Usage: sam filename
Program exited with code 1
setenv
command sets the environment variable
TEXT
to the value
sam.c
.
[Return to example]
run
command executes the program from the beginning. The program reads
input from the file named in the the environment variable
TEXT
.
Program execution stops at the breakpoint at line 52.
[Return to example]
setenv
command sets the environment variable
TEXT
to null.
[Return to example]
run
command executes the program. Because the
TEXT
environment variable contains a null value, the program must get input.
[Return to example]
A breakpoint stops program execution and lets you examine the program's
state at that point. The following sections describe the
dbx
commands to set a breakpoint at a specific line or in a procedure and
to stop for signals.
When a program stops at a breakpoint, the debugger displays an
informational message. For example, if a breakpoint is set in the
sample program
sam.c
at line 23 in the
main()
procedure, the following message is displayed:
[4] stopped at [main:40, 0x120000b18] i=strlen(line1.string); | | | | | [1] [2] [3] [4] [5]
Before setting a breakpoint in a program with multiple source files, be sure that you are setting the breakpoint in the right file. To select the right procedure, take the following steps:
file
command to select the source file.
func
command to specify a procedure name.
list
command (see
Section 5.6.4).
stop
at
command to set a breakpoint at the desired line.
For debugging programs written in high-level languages, the
stop
command sets breakpoints to stop at a line, when a variable changes or
a specified condition is true, or in a procedure. For debugging
programs written in assembly language, the
stopi
command works the same as
stop
,
except that it traces by machine instructions instead of by program
lines. You can also instruct
dbx
to stop when it enters a new image invoked by an
exec(
)
call by setting the
$stop_on_exec
predefined variable (see
Table 5-8).
stop
at
and
stopi
at
commands set a breakpoint at a specific source code line or address, as
applicable. The
dbx
debugger stops only at lines or addresses that have executable code.
If you specify a nonexecutable stopping point,
dbx
sets the breakpoint at the next executable point. If you specify the
VAR
parameter, the debugger displays the variable and stops only when
VAR
changes; if you specify
if
EXP
,
the debugger stops only when
EXP
is true.
stop
in
and
stopi
in
commands set a breakpoint at the beginning or, conditionally, for the
duration of a procedure.
stop
if
and
stopi
if
commands cause
dbx
to stop program execution under specified conditions.
Because
dbx
must check the condition after the execution of each line, this command
slows program execution markedly. Whenever possible, use
stop/stopi
at
or
stop/stopi
in
instead of
stop/stopi
if
.
$stop_on_exec
predefined variable is set to 1, an
exec(
)
call causes
dbx
to stop and read in the new image's symbol table, then advance to the
image's main activation point and stop for user input.
Use the
delete
command to remove breakpoints established by the
stop
or
stopi
command.
The
stop
and
stopi
commands have the following forms:
stop
VAR
stopi
VAR
VAR
changes.
stop
VAR
at
LINE
stopi
VAR
at
ADDRESS
VAR
changes at a specified source code line or address.
stop
VAR
at
LINE
if
EXP
stopi
VAR
at
ADDRESS
if
EXP
VAR
changes at a specified line or address only if the expression is true.
stop
if
EXP
stopi
if
EXP
EXP
is true.
stop
VAR
if
EXP
stopi
VAR
if
EXP
VAR
changes if
EXP
is true.
stop
in
PROCEDURE
stopi
in
PROCEDURE
stop
VAR
in
PROCEDURE
VAR
changes.
stop
VAR
in
PROCEDURE
if
EXP
stopi
VAR
in
PROCEDURE
if
EXP
VAR
changes in the specified procedure if
EXP
is true.
Note
Specifying both
VAR
andEXP
causes stops anywhere in the procedure, not just at the beginning. Using this feature is time consuming because the debugger must check the condition before and after each source line is executed. (When both arguments are specified,EXP
is always checked beforeVAR
.)
The following example shows the use of
stop
in a C program:
(dbx)
stop at 52
[3] stop at "sam.c":52
(dbx)
rerun
[3] stopped at [prnt:52,0x120000fb0] fprintf(stdout,"%3d.(%3d) %s",
(dbx)
stop in prnt
[15] stop in prnt
(dbx)
The following example shows the use of
stopi
in an assembly-language program:
(dbx)
stopi at 0x120000c04
[4] stop at 0x120000c04
(dbx)
rerun
[7] stopped at >*[prnt:52 ,0x120000c04] ldq r16, -32640(gp)
For debugging programs written in high-level languages, the
trace
command lists the value of a variable while the program is executing
and determines the scope of the variable being traced. For debugging
programs written in assembly language, the
tracei
command works the same as
trace
,
except that it traces by machine instructions instead of by program
lines.
The
trace
and
tracei
commands have the following forms:
trace
LINE
trace
VAR
tracei
VAR
trace
[VAR]
at
LINE
tracei
[VAR]
at
ADDRESS
trace
[VAR]
in
PROCEDURE
tracei
[VAR]
in
PROCEDURE
trace
[VAR]
at
LINE
if
EXP
tracei
[VAR]
at
ADDRESS
if
EXP
EXP
is checked before
VAR
.)
trace
[VAR]
in
PROCEDURE
if
EXP
tracei
[VAR]
in
PROCEDURE
if
EXP
EXP
is checked before
VAR
.)
For example:
(dbx)
trace i
[5] trace i in main
(dbx)
rerun sam.c
[4] [main:25 ,0x400a50]
(dbx)
c
[5] i changed before [main: line 41]: new value = 19; [5] i changed before [main: line 41]: old value = 19; new value = 14; [5] i changed before [main: line 41]: old value = 14; new value = 19; [5] i changed before [main: line 41]: old value = 19; new value = 13; [5] i changed before [main: line 41]: old value = 13; new value = 17; [5] i changed before [main: line 41]: old value = 17; new value = 3; [5] i changed before [main: line 41]: old value = 3; new value = 1; [5] i changed before [main: line 41]: old value = 1; new value = 30;
Use the
when
command to control the conditions under which certain
dbx
commands that you specify will be executed.
The
when
command has the following forms:
when
VAR
[if
EXP]
{COMMAND_LIST}
EXP
is true and
VAR
changes.
when
[VAR]
at
LINE
[if
EXP]
{COMMAND_LIST}
EXP
is true,
VAR
changes, and the debugger encounters
LINE
.
when
in
PROCEDURE
{COMMAND_LIST}
PROCEDURE
.
when
[VAR]
in
PROCEDURE
[if
EXP]
{COMMAND_LIST}
PROCEDURE
when
EXP
is true and
VAR
changes.
(EXP
is checked before
VAR
.)
For example:
(dbx)
when in prnt {print line1.length}
[6] print line1.length in prnt
(dbx)
rerun
19 [1] 14 19
.
.
.
17 59 45 12
More (n if no)?
(dbx)
delete 6
(dbx)
when in prnt {stop}
[7] stop in prnt
(dbx)
rerun
[7] stopped at [prnt:52,0x12000fb0] fprintf(stdout,"%3d.(%3d) %s", | [2]
line1.length
.
[Return to example]
prnt
.
[Return to example]
The
catch
command either lists the signals that
dbx
catches or specifies a signal for
dbx
to catch. If the process encounters a specified signal,
dbx
stops the process.
The
ignore
command either lists the signals that
dbx
does not catch or specifies a signal for
dbx
to add to the ignore list.
The
catch
and
ignore
commands have the following forms:
catch
dbx
catches.
catch
SIGNAL
ignore
dbx
does not catch.
ignore
SIGNAL
For example:
(dbx)
catch [1]
INT QUIT ILL TRAP ABRT EMT FPE BUS SEGV SYS PIPE TERM URG \ STOP TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2
(dbx)
ignore [2]
HUP KILL ALRM TSTP CONT CHLD
(dbx)
catch kill [3]
(dbx)
catch
INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE TERM URG \ STOP TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2
(dbx)
ignore
HUP ALRM TSTP CONT CHLD
(dbx)
The backslashes in this example represent line continuation. The
actual output from
catch
and
ignore
is a single line.
KILL
to the catch list and removes
KILL
from the ignore list.
[Return to example]
When
dbx
is stopped at a breakpoint, the program state can be examined to
determine what might have gone wrong. The debugger provides commands
for displaying stack traces, variable values, and register values. The
debugger also provides commands to display information about the
activation levels shown in the stack trace and to move up and down the
activation levels (see
Section 5.6.2).
The
print
command displays the values of one or more expressions.
The
printf
command lists information in a specified format and supports all
formats of the
printf()
function except strings
(%s
).
For a list of formats, see
printf
(3).
You can use the
printf
command to see a variable's value in a different number base.
The default command alias list (see
Section 5.5.3)
provides some useful aliases for displaying the value of variables in
different bases -- octal
(po
),
decimal
(pd
),
and hexadecimal
(px
).
The default number base is decimal.
You can specify either the real machine register names or the
software names from the include file
regdef.h
.
A prefix before the register number specifies the type of register; the
prefix can be either
$f
or
$r
,
as shown in the following listing of registers:
Register Name(s) | Register Type |
|
Floating point register (1 of 32) |
|
Machine register (1 of 32) |
$fpcr
|
Floating-point control register |
$pc
|
Program counter value |
$ps
|
Program status register |
Table Note:
You can also specify prefixed registers in the
print
command to display a register value or the program counter. The
following commands display the values of machine register 3 and the
program counter:
(dbx)
print $r3
(dbx)
print $pc
The
print
command has the following forms:
print
EXP1,...,EXPN
printf
"STRING",
EXP1,...,EXPN
Note
If the expression contains a name that is the same as a
dbx
keyword, you must enclose the name within parentheses. For example, to printoutput
, a keyword in theplayback
andrecord
commands, specify the name as follows:
(dbx) print (output)
For example:
(dbx)
print i
14 [1]
(dbx)
po i
016 [2]
(dbx)
px i
0xe [3]
(dbx)
pd i
14 [4]
(dbx)
The
printregs
command displays a complete list of register values; it
accepts no arguments. As with the
print
command, the default base for display by
printregs
is decimal. To display values in hexadecimal with the
printregs
command, set the
dbx
variable
$hexints
.
For example:
(dbx)
printregs
$vfp= 4831837712 $r0_v0=0 $r1_t0=0 $r2_t1=0 $r3_t2=18446744069416926720 $r4_t3=18446744071613142936 $r5_t4=1 $r6_t5=0
.
.
.
$f25= 0.0 $f26= 0.0 $f27= 2.3873098155006918e-314 $f28= 2.6525639909000367e-314 $f29= 9.8813129168249309e-324 $f30= 2.3872988413145664e-314 $f31= 0.0 $pc= 4831840840
The
dump
command displays information about activation levels, including values
for all variables that are local to a specified activation level. To
see what activation levels are currently active in the program, use the
where
command to get a stack trace.
The
dump
command has the following forms:
dump
dump .
dump
PROCEDURE
For example:
(dbx)
where
> 0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04] 1 main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac]
(dbx)
dump
prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04]
(dbx)
dump .
> 0 prnt(pline = 0x11ffffcb8) ["sam.c":52, 0x120000c04]
1 main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac] line1 = struct { string = "#include <stdio.h>" length = 19 linenumber = 0 } fd = 0x140000158 fname = 0x11ffffe9c = "sam.c" i = 19 curlinenumber = 1
(dbx)
dump main
main(argc = 2, argv = 0x11ffffe08) ["sam.c":45, 0x120000bac] line1 = struct { string = "#include <stdio.h>" length = 19 linenumber = 0 } fd = 0x140000158 fname = 0x11ffffe9c = "sam.c" i = 19 curlinenumber = 1 (dbx)
You can display memory contents by specifying the address and the format of the display. Use the following form, with no spaces between the three parts of the command:
address
/count
mode
The
address
portion of the command is the address of the first item to be
displayed,
count
is the number of items to be shown, and
mode
indicates the format in which the items are to be displayed. For
example:
prnt/20i
This example displays the contents of 20 machine instructions,
beginning at the address of the
prnt
function.
The values
for
mode
are shown in
Table 5-9.
Mode | Display Format |
b
|
Displays a byte in octal. |
c
|
Displays a byte as a character. |
D
|
Displays a long word (64 bits) in decimal. |
d
|
Displays a short word (16 bits) in decimal. |
dd
|
Displays a word (32 bits) in decimal. |
f
|
Displays a single-precision real number. |
g
|
Displays a double-precision real number. |
i
|
Displays machine instructions. |
O
|
Displays a long word in octal. |
o
|
Displays a short word in octal. |
oo
|
Displays a word (32 bits) in octal. |
s
|
Displays a string of characters that ends in a null byte. |
X
|
Displays a long word in hexadecimal. |
x
|
Displays a short word in hexadecimal. |
xx
|
Displays a word (32 bits) in hexadecimal. |
The following example shows the output when displaying memory addresses
as instructions:
(dbx)
&prnt/20i
[prnt:51, 0x120000bf0] ldah gp, 8193(r27) [prnt:51, 0x120000bf4] lda gp, -25616(gp) [prnt:51, 0x120000bf8] lda sp, -64(sp) [prnt:51, 0x120000bfc] stq r26, 8(sp) [prnt:51, 0x120000c00] stq r16, 16(sp) [prnt:52, 0x120000c04] ldq r16, -32640(gp) >*[prnt:52, 0x120000c08] addq r16, 0x38, r16 [prnt:52, 0x120000c0c] ldq r17, -32552(gp) [prnt:52, 0x120000c10] ldq r1, 16(sp) [prnt:52, 0x120000c14] ldl r18, 260(r1) [prnt:52, 0x120000c18] ldl r19, 256(r1) [prnt:52, 0x120000c1c] bis r1, r1, r20 [prnt:52, 0x120000c20] ldq r27, -32624(gp) [prnt:52, 0x120000c24] jsr r26, (r27), 0x4800030a0 [prnt:52, 0x120000c28] ldah gp, 8193(r26) [prnt:52, 0x120000c2c] lda gp, -25672(gp) [prnt:54, 0x120000c30] ldq r16, -32640(gp) [prnt:54, 0x120000c34] addq r16, 0x38, r16 [prnt:54, 0x120000c38] ldq r27, -32544(gp) [prnt:54, 0x120000c3c] jsr r26, (r27), 0x480003100
The
dbx
debugger allows you to capture and replay portions of your input to the
program and also portions of its output. Recorded information is
written to a file so that you can reuse or reexamine it.
Recording input can be useful for creating command files containing
sequences that you want to repeat many times; you can even use recorded
input to control
dbx
for such purposes as regression testing. Recording output is useful
for capturing large volumes of information that are inconvenient to
deal with on the screen, so that you can analyze them later. To look
at recorded output later, you can read the saved file directly or you
can play it back with
dbx
.
Use the
record
input
command to record debugger input. Use the
playback
input
command to repeat a recorded sequence. The
record
input
and
playback
input
commands have the following forms:
record
input
[FILE]
dbx
commands in the specified file or, if no file is specified, in a
file placed in
/tmp
and given a generated name.
playback
input
[FILE]
source [FILE]
The name given to the temporary file, if used, is contained in the
debugger variable
$defaultin
.
To display the temporary file name, use the
print
command:
(dbx)
print $defaultin
Use a temporary file when you need to refer to the saved output only
during the current debugging session; specify a file name to save
information for reuse after you end the current debugging session. Use
the
status
command to see whether recording is active. Use the
delete
command to stop recording. Note that these commands will appear in
the recording; if you are creating a file for future use, you will
probably want to edit the file to remove commands of this type.
Use the
playback
input
command to replay the commands recorded with the
record
input
command. By default, playback is silent; you do not see the commands
as they are played. If the
dbx
variable
$pimode
is set to 1,
dbx
displays commands as they are played back.
The following example records input and displays the resulting file:
(dbx)
record input [1]
[2] record input /tmp/dbxtX026963 (0 lines)
(dbx)
status
[2] record input /tmp/dbxtX026963 (1 lines)
(dbx)
stop in prnt
[3] stop in prnt
(dbx)
when i = 19 {stop}
[4] stop ifchanged i = 19
(dbx)
delete 2 [2]
(dbx)
playback input [3]
[3] stop in prnt [4] stop ifchanged i = 19 [5] stop in prnt [6] stop ifchanged i = 19 /tmp/dbxtX026963: 4: unknown event 2 [4]
(dbx)
The temporary file resulting from the preceding
dbx
commands contains the following text:
status stop in prnt when i = 19 {stop} delete 2
Use the
record
output
command to record
dbx
output during a debugging session. To produce a complete record of
activity by recording input along with the output, set the
dbx
variable
$rimode
.
You can use the debugger's
playback
output
command to look at the recorded information, or you can use any text
editor.
The
record
output
and
playback
output
commands have the following forms:
record
output
[FILE]
dbx
output in the specified file or, if no file is specified, in a
file placed in
/tmp
and given a generated name.
playback
output
[FILE]
The name given to the temporary file, if used, is contained in the
debugger variable
$defaultout
.
To display the temporary file name, use the
print
command:
(dbx)
print $defaultout
The
playback
output
command works the same as the
cat
command; a display from the
record
output
command is identical to the contents of the recording file.
Use a temporary file when you need to refer to the saved output only
during the current debugging session; specify a file name to save
information for reuse after you end the current debugging session. Use
the
status
command to see whether recording is active. Use the
delete
command to stop recording.
The following example shows a sample
dbx
interaction and the output recorded for this interaction in a file
named
code
:
(dbx)
record output code
[3] record output code (0 lines)
(dbx)
stop at 25
[4] stop at "sam.c":25
(dbx)
run sam.c
[4] stopped at [main:25 ,0x120000a48] if (argc < 2) {
(dbx)
delete 3
(dbx)
playback output code
[3] record output code (0 lines) (dbx) [4] stop at "sam.c":25 (dbx) [4] stopped at [main:25 ,0x120000a48] if (argc < 2) {
(dbx)
The
dbx
debugger can be used to debug running processes that are started
outside the
dbx
environment. It supports the debugging of such processes, both
parent and child, by using the
/proc
file system. The debugger can debug running processes only if the
/proc
file system is mounted. If
/proc
is not already mounted, the superuser can mount it with the following
command:
#
mount -t procfs /proc /proc
You can add the following entry to the
/etc/fstab
file to mount
/proc
upon booting:
/proc /proc procfs rw 0 0
The
dbx
debugger checks first to see if
/proc
is mounted, but it will still function if this is not the case.
To attach to a running process, use the
dbx
command
attach
,
which has the following form:
attach
process-id
process-id
argument is the process ID of the process you want to attach to.
You can also attach to a process for debugging by using the command
line flag
-pid process id
.
To detach from a running process, use the
dbx
command
detach
,
which has the following form:
detach
[process-id
]
process-id
argument is the process ID of the process you want to detach from. If
no argument is given,
dbx
detaches from the current process.
To change from one process to another, use the
dbx
command
switch
,
which has the following form:
switch
process-id
process-id
argument is the process ID of the process you want to switch to. You
must already have attached to a process before you can switch to it.
You can use the alias
sw
for the
switch
command.
The
attach
command first checks to see whether
/proc
is mounted;
dbx
gives a warning that tells you what to do if it is not mounted. If
/proc
is mounted,
dbx
looks for the process ID in
/proc
.
If the process ID is in
/proc
,
dbx
attempts to open the process and issues a
stop
command. If the process is not there or if the permissions do not allow
attaching to it,
dbx
reports this failure.
When the
stop
command takes effect,
dbx
reports the current position, issues a prompt, and waits for user
commands. The program probably will not be stopped
directly in the user code but will more likely be in a library or
system call that was called by user code.
The
detach
command deletes all current breakpoints, sets up a "run on last
close" flag, and closes ("releases") the process. The program
then continues running if it has not been explicitly terminated
inside
dbx
.
To see a summary of all the active processes under control of
dbx
,
use the
plist
command, which has the following form:
plist
-->
The
dbx
debugger provides four basic commands to assist in the debugging of
applications that use threads.
The
tlist
command displays a quick list of all threads and where they are
currently positioned in the program. This command accepts no
arguments.
The
tset
command sets the current thread. The debugger maintains one thread as
the "current" thread; this thread is the one that hits a breakpoint
or receives a signal that causes it to stop and relinquish control to
dbx
.
Using the
tlist
command, you can see all the threads, with their IDs, that are
currently in your program. Use
tset
to choose a different thread as the current thread so that you
can examine its state with the usual
dbx
commands.
Note that the selected thread remains the current thread
until you enter another
tset
command. Note also that the
continue
,
step
,
or
next
commands might be inappropriate for a given thread if it is blocked or
waiting to join with another thread.
The
tset
command has the following form:
tset
[EXP]
EXP
argument is the hexadecimal ID of the desired thread.
The
tstack
command lists the stacks of all the threads in your application. It is
similar to the
where
command and, like
where
,
takes an optional numeric argument to limit the number of stack levels
displayed:
tstack
[EXP]
If
EXP
is specified,
dbx
displays only the top
EXP
levels of the stacks; otherwise, the entire stacks are displayed.
If the DECthreads product is installed on your system, you can gain
access to the DECthreads pthread debugger by issuing a
call
cma_debug()
command within your
dbx
session. The pthread debugger can provide a great deal of useful
information about the threads in your program. For information on
using the pthread debugger, enter a
help
command at its
debug>
prompt.
A sample threaded program,
twait.c
,
is shown in
Example 12-1.
The following example shows a
dbx
session using that program. Long lines in this example have all been
folded at 72 characters to represent display on a narrow terminal.
%
dbx twait
dbx version 3.11.6 Type 'help' for help.
main: 50 pthread_t me = pthread_self(), timer_thread;
(dbx)
stop in do_tick
[2] stop in do_tick
(dbx)
stop at 85
[3] stop at "twait.c":85
(dbx)
stop at 35
[4] stop at "twait.c":35
(dbx)
run
1: main thread starting up 1: exit lock initialized 1: exit lock obtained 1: exit cv initialized 1: timer_thread 2 created 1: exit lock released [2] thread 0x81c62e80 stopped at [do_tick:21 ,0x12000730c] pthread_ t me = pthread_self();
(dbx)
tlist
thread 0x81c623a0 stopped at [msg_receive_trap:74 +0x8,0x3ff808edf04] Source not available thread 0x81c62e80 stopped at [do_tick:21 ,0x12000730c] pthread_ t me = pthread_self();
(dbx)
where
> 0 do_tick(argP = (nil)) ["twait.c":21, 0x12000730c] 1 cma__thread_base(0x0, 0x0, 0x0, 0x0, 0x0) ["../../../../../src/usr/ ccs/lib/DECthreads/COMMON/cma_thread.c":1441, 0x3ff80931410]
(dbx)
tset 0x81c623a0
thread 0x81c623a0 stopped at [msg_receive_trap:74 +0x8,0x3ff808edf04] Source not available
(dbx)
where
> 0 msg_receive_trap(0x3ff8087b8dc, 0x3ffc00a2480, 0x3ff8087b928, 0x181 57f0d0d, 0x3ff8087b68c) ["/usr/build/osf1/goldos.bld/export/alpha/usr/in clude/mach/syscall_sw.h":74, 0x3ff808edf00] 1 msg_receive(0x61746164782e, 0x3ffc009a420, 0x3ffc009a420, 0x3c20, 0 xe0420) ["../../../../../src/usr/ccs/lib/libmach/msg.c":95, 0x3ff808e474 4] 2 cma__vp_sleep(0x280187f578, 0x3990, 0x7, 0x3ffc1032848, 0x0) ["../. ./../../../src/usr/ccs/lib/DECthreads/COMMON/cma_vp.c":1471, 0x3ff809375 cc] 3 cma__dispatch(0x7, 0x3ffc1032848, 0x0, 0x3ffc100ee08, 0x3ff80917e3c ) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_dispatch.c":967 , 0x3ff80920e48] 4 cma__int_wait(0x11ffff228, 0x140009850, 0x3ffc040cdb0, 0x5, 0x3ffc0 014c00) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_condition .c":2202, 0x3ff80917e38] 5 cma_thread_join(0x11ffff648, 0x11ffff9f0, 0x11ffff9e8, 0x60aaec4, 0 x3ff8000cf38) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_thr ead.c":825, 0x3ff80930a58] 6 pthread_join(0x140003110, 0x40002, 0x11ffffa68, 0x3ffc040cdb0, 0x0) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_pthread.c":2193, 0x3ff809286c8] 7 main() ["twait.c":81, 0x12000788c]
(dbx)
tlist
thread 0x81c623a0 stopped at [msg_receive_trap:74 +0x8,0x3ff808edf04] Source not available thread 0x81c62e80 stopped at [do_tick:21 ,0x12000730c] pthread_ t me = pthread_self();
(dbx)
tset 0x81c62e80
thread 0x81c62e80 stopped at [do_tick:21 ,0x12000730c] pthread_ t me = pthread_self();
(dbx)
cont
2: timer thread starting up, argP=0x0 [4] thread 0x81c62e80 stopped at [do_tick:35 ,0x120007430] printf(" %d: wait for next tick\n", THRID(&me));
(dbx)
cont
2: wait for next tick 2: TICK #1 [4] thread 0x81c62e80 stopped at [do_tick:35 ,0x120007430] printf(" %d: wait for next tick\n", THRID(&me));
(dbx)
tstack
Thread 0x81c623a0: > 0 msg_receive_trap(0x3ff8087b8dc, 0x3ffc00a2480, 0x3ff8087b928, 0x181 57f0d0d, 0x3ff8087b68c) ["/usr/build/osf1/goldos.bld/export/alpha/usr/in clude/mach/syscall_sw.h":74, 0x3ff808edf00] 1 msg_receive(0x61746164782e, 0x3ffc009a420, 0x3ffc009a420, 0x3c20, 0 xe0420) ["../../../../../src/usr/ccs/lib/libmach/msg.c":95, 0x3ff808e474 4] 2 cma__vp_sleep(0x280187f578, 0x3990, 0x7, 0x3ffc1032848, 0x0) ["../. ./../../../src/usr/ccs/lib/DECthreads/COMMON/cma_vp.c":1471, 0x3ff809375 cc] 3 cma__dispatch(0x7, 0x3ffc1032848, 0x0, 0x3ffc100ee08, 0x3ff80917e3c ) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_dispatch.c":967 , 0x3ff80920e48] 4 cma__int_wait(0x11ffff228, 0x140009850, 0x3ffc040cdb0, 0x5, 0x3ffc0 014c00) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_condition .c":2202, 0x3ff80917e38] 5 cma_thread_join(0x11ffff648, 0x11ffff9f0, 0x11ffff9e8, 0x60aaec4, 0 x3ff8000cf38) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_thr ead.c":825, 0x3ff80930a58] 6 pthread_join(0x140003110, 0x40002, 0x11ffffa68, 0x3ffc040cdb0, 0x0) ["../../../../../src/usr/ccs/lib/DECthreads/COMMON/cma_pthread.c":2193, 0x3ff809286c8] 7 main() ["twait.c":81, 0x12000788c] Thread 0x81c62e80: > 0 do_tick(argP = (nil)) ["twait.c":35, 0x120007430] 1 cma__thread_base(0x0, 0x0, 0x0, 0x0, 0x0) ["../../../../../src/usr/ ccs/lib/DECthreads/COMMON/cma_thread.c":1441, 0x3ff80931410] More (n if no)?
(dbx)
tstack 3
Thread 0x81c623a0: > 0 msg_receive_trap(0x3ff8087b8dc, 0x3ffc00a2480, 0x3ff8087b928, 0x181 57f0d0d, 0x3ff8087b68c) ["/usr/build/osf1/goldos.bld/export/alpha/usr/in clude/mach/syscall_sw.h":74, 0x3ff808edf00] 1 msg_receive(0x61746164782e, 0x3ffc009a420, 0x3ffc009a420, 0x3c20, 0 xe0420) ["../../../../../src/usr/ccs/lib/libmach/msg.c":95, 0x3ff808e474 4] 2 cma__vp_sleep(0x280187f578, 0x3990, 0x7, 0x3ffc1032848, 0x0) ["../. ./../../../src/usr/ccs/lib/DECthreads/COMMON/cma_vp.c":1471, 0x3ff809375 cc] Thread 0x81c62e80: > 0 do_tick(argP = (nil)) ["twait.c":35, 0x120007430] 1 cma__thread_base(0x0, 0x0, 0x0, 0x0, 0x0) ["../../../../../src/usr/ ccs/lib/DECthreads/COMMON/cma_thread.c":1441, 0x3ff80931410]
(dbx)
cont
2: wait for next tick 2: TICK #2 [4] thread 0x81c62e80 stopped at [do_tick:35 ,0x120007430] printf(" %d: wait for next tick\n", THRID(&me));
(dbx)
assign ticks = 29
29
(dbx)
cont
2: wait for next tick 2: TICK #29 [4] thread 0x81c62e80 stopped at [do_tick:35 ,0x120007430] printf(" %d: wait for next tick\n", THRID(&me));
(dbx)
cont
2: wait for next tick 2: TICK #30 2: exiting after #31 ticks 1: joined with timer_thread 2 [3] thread 0x81c623a0 stopped at [main:85 ,0x1200078ec] if (errn o != 0) printf("errno 7 = %d\n",errno);
(dbx)
tlist
thread 0x81c623a0 stopped at [main:85 ,0x1200078ec] if (errno != 0) printf("errno 7 = %d\n",errno); thread 0x81c62e80 stopped at [msg_rpc_trap:75 +0x8,0x3ff808edf10] Source not available
(dbx)
cont
Program terminated normally
(dbx)
tlist
(dbx)
quit
The
dbx
debugger can debug multiple simultaneous asynchronous processes. While
debugging asynchronous processes,
dbx
can display status and accept commands asynchronously. When running
asynchronously, the debugger might exhibit confusing behavior because a
running process can display output on the screen while you are entering
commands to examine a different process that is stopped.
The debugger automatically enters asynchronous mode in either of the following circumstances:
dbx
is attached forks off a child process, and the debugger automatically
attaches to the child process without detaching from the parent.
The debugger uses several predefined variables to define the behavior
of asynchronous debugging. (See also
Table 5-8.)
The variable
$asynch_interface
can be viewed as a counter that is incremented by 1 when a new process
is attached and decremented by 1 when a process terminates or is
detached. The default value is 0.
When
$asynch_interface
has a positive nonzero value, asynchronous debugging is enabled;
when the variable is 0 (zero) or negative, asynchronous debugging is
disabled. To prevent
dbx
from entering asynchronous mode, set the
$asynch_interface
variable to a negative value. (Note that disabling asynchronous mode
might make debugging more difficult if a parent is waiting on a child
that is stopped.)
When a process executes a
fork(
)
or
vfork(
)
call,
dbx
attaches to the child process and automatically enters asynchronous
mode (if permitted by
$asynch_interface
).
The default behavior is to stop the child process right after the fork.
You can change this default by setting the variable
$stop_on_fork
to 0; in this case,
dbx
will attach to the child process but not stop it.
The
dbx
debugger attempts to apply a degree of intelligence to the handling of
forks by filtering out many of the fork calls made by various system
and library calls. If you want to stop the process on these forks
also, you can set the predefined variable
$stop_all_forks
to 1. This variable's default value is 0. Stopping on all forks can
be particularly useful when you are debugging a library routine.
You can use the debugger's
plist
and
switch
commands to monitor and switch between processes.
Example 5-1
is the sample C program
(sam.c
)
that is referred to in examples throughout this chapter.
#include <stdio.h> struct line { char string[256]; int length; int linenumber; };
typedef struct line LINETYPE;
void prnt();
main(argc,argv) int argc; char **argv; { LINETYPE line1; FILE *fd; extern FILE *fopen(); extern char *fgets(); extern char *getenv(); char *fname; int i; static curlinenumber=0;
if (argc < 2) { if((fname = getenv("TEXT")) == NULL || *fname == '') { fprintf(stderr, "Usage: sam filename\n"); exit(1); } } else fname = argv[1]; fd = fopen(fname,"r"); if (fd == NULL) { fprintf(stderr, "cannot open %s\n",fname); exit(1); } while(fgets(line1.string, sizeof(line1.string), fd) != NULL){ i=strlen(line1.string); if (i==1 && line1.string[0] == '\n') continue; line1.length = i; line1.linenumber = curlinenumber++; prnt(&line1); } } void prnt(pline) LINETYPE *pline; { fprintf(stdout,"%3d. (%3d) %s", pline->linenumber, pline->length, pline->string); fflush(stdout); }