Debugging a Program With dbx |
Event Management
Event management refers to the capability of
dbx
to perform actions when events take place in the program being debugged.This chapter is organized into the following sections:
- Event Handlers
- Creating Event Handlers
- Manipulating Event Handlers
- Using Event Counters
- Setting Event Specifications
- Parsing and Ambiguity
- Using Predefined Variables
- Setting Event Handler Examples
Event Handlers
Event management is based on the concept of a handler. The name comes from an analogy with hardware interrupt handlers. Each event management command typically creates a handler, which consists of an event specification and a series of side-effect actions. (See Setting Event Specifications.) The event specification specifies the event that will trigger the handler.
When the event occurs and the handler is triggered, the handler evaluates the event according to any modifiers included in the event specification. (See Event Specification Modifiers.) If the event meets the conditions imposed by the modifiers, the handler's side-effect actions are performed (that is, the handler "fires").
An example of the association of a program event with a
dbx
action is setting a breakpoint on a particular line.The most generic form of creating a handler is by using the
when
command.
when
event-specification{
action; ... }
Examples in this chapter show how you can write a command (like
stop
,step
, orignore
) in terms ofwhen
. These examples are meant to illustrate the flexibility ofwhen
and the underlying handler mechanism, but they are not always exact replacements.Creating Event Handlers
Use the commands
when
,stop
, andtrace
to create event handlers.
stop
is shorthand for a commonwhen
idiom.
when
event-specification{ stop -update; whereami; }
An event-specification is used by the event management commands
stop
,when
, andtrace
to specify an event of interest. (see Setting Event Specifications).Most of the
trace
commands can be handcrafted using thewhen
command,ksh
functionality, and event variables. This is especially useful if you want stylized tracing output.For detailed information, see "when Command," "stop Command," and "trace Command" in the Using dbx Commands section of the Sun WorkShop online help.
Every command returns a number known as a handler id (hid). You can access this number using the predefined variable
$newhandlerid
.An attempt has been made to make the
stop
andwhen
commands conform to the handler model. However, backward compatibility with previousdbx
releases forces some deviations.For example, the following samples from an earlier
dbx
release are equivalent.
when
cond bodywhen step -if
cond bodywhen
condin
funcbody
when next -if
cond-in
funcbody
These samples illustrate that cond is not a pure event; there is no internal handler for conditions.
Manipulating Event Handlers
You can use the following commands to manipulate event handlers. For more information on each command, see the cited topic in the Using dbx Commands section of the Sun WorkShop online help.
status
- lists handlers (see "status Command").delete
- deletes all handlers including temporary handlers (see "delete Command").clear
- deletes handlers based on breakpoint position (see "clear Command").handler -enable
- enables handlers (see "handler Command").handler -disable
- disables handlers.cancel
- cancels signals and lets the process continue (see "cancel Command").Using Event Counters
An event handler has a trip counter, which has a count limit. Whenever the specified event occurs, the counter is incremented. The action associated with the handler is performed only if the count reaches the limit, at which point the counter is automatically reset to 0. The default limit is 1. Whenever a process is rerun, all event counters are reset.
You can set the count limit using the
-count
modifier with astop
,when
, ortrace
command (see -count n -count infinity). Otherwise, use thehandler
command to individually manipulate event handlers:.
handler [ -count | -reset ] hid
new-countnew-count-limit
Setting Event Specifications
Event specifications are used by the
stop,
when
, andtrace
commands to denote event types and parameters. The format consists of a keyword representing the event type and optional parameters. For more information, see "Event Specification" in the Using dbx Commands section of the Sun WorkShop online help.Breakpoint Event Specifications
The following are event specifications for breakpoint events.
in
functionThe function has been entered, and the first line is about to be executed. If the
-instr
modifier is used (see -instr), it is the first instruction of the function about to be executed. The func specification can take a formal parameter signature to help with overloaded function names or template instance specification. For example:
stop in mumble(int, float, struct Node *)
Note Do not confusein
function with the-in
function modifier.
at [
filename:]
linenoThe designated line is about to be executed. If you specify filename, then the designated line in the specified file is about to be executed. The file name can be the name of a source file or an object file. Although quotation marks are not required, they may be necessary if the file name contains special characters. If the designated line is in template code, a breakpoint is placed on all instances of that template.
infunction
functionEquivalent to
in
function for all overloaded functions named function or all template instantiations thereof.
inmember
functioninmethod
functionEquivalent to
in
function for the member function named function for every class.
inclass
classnameEquivalent to
in
function for all member functions that are members of classname.
inobject
object-expressionA member function called on the specific object at the address denoted by object-expression has been called.
Watchpoint Event Specifications
The following are event specifications for watchpoint events. For more information, see "Watchpoint Specification" in the Using dbx Commands section of the Sun WorkShop online help.
access
mode addr-expression [, byte-size-expression]The memory specified by addr-expression has been accessed.
mode specifies that the memory was accessed. It can be composed of one or all of the letters:
r
The memory has been read. w
The memory has been written to. x
The memory has been executed.
mode can also contain either of the following:
a
Stops the process after the access (default). b
Stops the process before the access.
In both cases the program counter will point at the offending instruction. The "before" and "after" refer to the side effect.
address-expression is any expression that can be evaluated to produce an address. If you give a symbolic expression, the size of the region to be watched is automatically deduced; you can override it by specifying byte-size-expression. You can also use nonsymbolic, typeless address expressions; in which case, the size is mandatory. For example:
stop access 0x5678, sizeof(Complex)
The
access
command has the limitation that no two matched regions may overlap.
Note Theaccess
event specification is a replacement for themodify
event specification. While both syntaxes work on Solaris 2.6, Solaris 7, and Solaris 8, on all of these operating environments except Solaris 2.6,access
suffers the same limitations asmodify
and accepts only a mode ofwa
.
change
variableThe value of variable has changed.
cond
condition-expressionThe condition denoted by cond-expression evaluates to true. You can specify any expression for cond-expression, but it must evaluate to an integral type.
modify
address-expression[,
byte-size-expression]
The specified address range has been modified. This is the older watchpoint facility.
address-expression is any expression that can be evaluated to produce an address. If you give a symbolic expression, the size of the region to be watched is automatically deduced; you can override it by specifying byte-size-expression. You can also use nonsymbolic, typeless address expressions; in which case, the size is mandatory. For example:
stop modify 0x5678, sizeof(Complex)
Note Multithreaded applications are prone to deadlock so mt watchpoints are nominally disallowed. They can be turned on by setting thedbx
environment variablemt_watchpoints
.
System Event Specifications
The following are event specifications for system events.
dlopen [
lib-path] | dlclose [
lib-path]
These events occur after a
dlopen
() or adlclose
() call succeeds. Adlopen
() ordlclose
() call can cause more than one library to be loaded. The list of these libraries is always available in the predefined variable$dllist
. The first word in$dllist
is a "+" or a "-", indicating whether the list of libraries is being added or deleted.lib-path is the name of a shared library. If it is specified, the event occurs only if the given library was loaded or unloaded. In that case,
$dlobj
contains the name of the library.$dllist
is still available.If lib-path begins with a
/
, a full string match is performed. Otherwise, only the tails of the paths are compared.If lib-path is not specified, then the events always occur whenever there is any
dl
-activity. In this case,$dlobj
is empty but$dllist
is valid.
fault
faultThe
fault
event occurs when the specified fault is encountered. The faults are architecture-dependent. The following set of faults known todbx
is defined in theproc
(4) man page.
Note BPT
,TRACE
, andBOUNDS
are used bydbx
to implement breakpoints, single-stepping, and watchpoints. Handling them might interfere with howdbx
works.
These faults are taken from /
sys/fault.h
. fault can be any of those listed above, in uppercase or lowercase, with or without theFLT
- prefix, or the actual numerical code.
lwp_exit
The
lwp_exit
event occurs whenlwp
has been exited.$lwp
contains the id of the exited LWP (lightweight process).
sig
sigThe
sig
sig event occurs when the signal is first delivered to the program being debugged. sig can be either a decimal number or the signal name in uppercase or lowercase; the prefix is optional. This is completely independent of thecatch/ignore
commands, although thecatch
command can be implemented as follows:
function simple_catch {when sig $1 {stop;echo Stopped due to $sigstr $sigwhereami}}
Note When thesig
event is received, the process has not seen it yet. Only if you continue the process with the specified signal is the signal forwarded to it.
sig
sigsub-code
When the specified signal with the specified sub-code is first delivered to the child, the
sig
sig sub-code event occurs. As with signals, you can type the sub-code as a decimal number, in uppercase or lowercase; the prefix is optional.
sysin
code|
nameThe specified system call has just been initiated, and the process has entered kernel mode.
The concept of system call supported by
dbx
is that provided by traps into the kernel as enumerated in/usr/include/sys/syscall.h
.This is not the same as the ABI notion of system calls. Some ABI system calls are partially implemented in user mode and use non-ABI kernel traps. However, most of the generic system calls (the main exception being signal handling) are the same between
syscall.h
and the ABI.
sysout
code|
nameThe specified system call is finished, and the process is about to return to user mode.
sysin
|
sysout
Without arguments, all system calls are traced. Certain
dbx
features, for example, themodify
event and runtime checking, cause the child to execute system calls for its own purposes and show up if traced.Execution Progress Event Specifications
The following are event specifications for events pertaining to execution progress.
next
The
next
event is similar to thestep
event except that functions are not stepped into.
returns
The
returns
event is a breakpoint at the return point of the current visited function. The visited function is used so that you can use thereturns
event specification after giving a number ofstep
up
commands. Thereturns
event is always-temp
and can only be created in the presence of a live process.
returns
funcThe
returns
func event executes each time the given function returns to its call site. This is not a temporary event. The return value is not provided, but you can find integral return values by accessing the following registers:
Sparc $o0
Intel $eax
The event is another way of saying:
when in func { stop returns; }
step
The
step
event occurs when the first instruction of a source line is executed. For example, you can get simple tracing with:
when step { echo $lineno: $line; }When enabling a step event, you instruct
dbx
to single-step automatically next time thecont
command is used. You can implement thestep
command as follows:
alias step="when step -temp { whereami; stop; }; cont"Other Event Specifications
The following are event specifications for other types of events.
attach
dbx
has successfully attached to a process.
detach
dbx has successfully detached from the program being debugged.
lastrites
The process being debugged is about to expire. This can happen for the following reasons:
- The
_exit
(2) system call has been called. (This happens either through an explicit call or whenmain
() returns.)- A terminating signal is about to be delivered.
- The process is being killed by the
kill
command.
proc_gone
The
proc_gone
event occurs whendbx
is no longer associated with a debugged process. The predefined variable$reason
may besignal
,exit
,kill
, ordetach
.
prog_new
The
prog_new
event occurs when a new program has been loaded as a result offollow
exec
.
Note Handlers for this event are always permanent.
stop
The process has stopped. The
stop
event occurs whenever the process stops such that the user receives a prompt, particularly in response to astop
handler. For example, the following commands are equivalent:
display x
when stop {print x;}
sync
The process being debugged has just been executed with
exec
(). All memory specified ina.out
is valid and present, but preloaded shared libraries have not been loaded. For example,printf
, although available todbx
, has not been mapped into memory.A
stop
on this event is ineffective; however, you can use thesync
event with thewhen
command.
syncrtld
The
syncrtld
event occurs after async
(orattach
if the process being debugged has not yet processed shared libraries). It executes after the dynamic linker startup code has executed and the symbol tables of all preloaded shared libraries have been loaded, but before any code in the.init
section has run.A
stop
on this event is ineffective; however, you can use thesyncrtld
event with thewhen
command.
throw
The
throw
event occurs whenever any exception that is not unhandled or unexpected is thrown by the application.
throw
typeIf an exception type is specified with the
throw
event, only exceptions of that type cause thethrow
event to occur.
throw -unhandled
-unhandled
is a special exception type signifying an exception that is thrown but for which there is no handler.
throw -unexpected
-unexpected
is a special exception type signifying an exception that does not satisfy the exception specification of the function that threw it.
timer
secondsThe
timer
event occurs when the program being debugged has been running for seconds. The timer used with this event is shared withcollector
command. The resolution is in milliseconds, so a floating point value for seconds is acceptable.Event Specification Modifiers
An event specification modifier sets additional attributes of a handler, the most common kind being event filters. Modifiers must appear after the keyword portion of an event specification. A modifier begins with a dash (
-
). The following are the valid event specification modifiers.
-if
conditionThe condition is evaluated when the event specified by the event specification occurs. The side effect of the handler is allowed only if the condition evaluates to nonzero.
If the
-if
modifier is used with an event that has an associated singular source location, such asin
orat
, condition is evaluated in the scope corresponding to that location. Otherwise, qualify it with the desired scope.
-in
functionThe handler is active only while within the given function or any function called from function. The number of times the function is entered is reference counted to properly deal with recursion.
-disable
The
-disable
modifier creates the handler in the disabled state.
-count
n-count infinity
The
-count
n and-count infinity
modifiers have the handler count from 0 (see Using Event Counters). Each time the event occurs, the count is incremented until it reaches n. Once that happens, the handler fires and the counter is reset to zero.Counts of all enabled handlers are reset when a program is run or rerun. More specifically, they are reset when the
sync
event occurs.
-temp
Creates a temporary handler. Once the event has occurred it is automatically deleted. By default, handlers are not temporary. If the handler is a counting handler, it is automatically deleted only when the count reaches 0 (zero).
Use the
delete
-temp
command to delete all temporary handlers.
-instr
Makes the handler act at an instruction level. This event replaces the traditional '
i
' suffix of most commands. It usually modifies two aspects of the event handler:
- Any message prints assembly-level rather than source-level information.
- The granularity of the event becomes instruction level. For instance,
step -instr
implies instruction-level stepping.
-thread
thread_IDThe action is executed only if the thread that caused the event matches thread_ID.
-lwp
lwp_IDThe action is executed only if the thread that caused the event matches lwp_ID.
-hidden
Hides the handler in a regular
status
command. Usestatus -h
to see hidden handlers.
-perm
Normally all handlers are thrown away when a new program is loaded. Using the
-perm
modifier retains the handler across debuggings. A plaindelete
command does not delete a permanent handler. Usedelete -p
to delete a permanent handler.Parsing and Ambiguity
The syntax for event specifications and modifiers is:
- Keyword driven
- Based on
ksh
conventions; everything is split into words delimited by spacesExpressions can have spaces embedded in them, causing ambiguous situations. For example, consider the following two commands:
when a -tempwhen a-temp
In the first example, even though the application might have a variable named temp, the
dbx
parser resolves the event specification in favor of-temp
being a modifier. In the second example,a-temp
is collectively passed to a language-specific expression parser. There must be variables named a and temp or an error occurs. Use parentheses to force parsing.Using Predefined Variables
Certain read-only
ksh
predefined variables are provided. The following variables are always valid:
As an example, consider that
whereami
can be implemented as:
function whereami {
echo Stopped in $func at line $lineno in file $(basename $file)
echo "$lineno\t$line"
}Variables Valid for
when
CommandThe following variables are valid only within the body of a
when
command.
$handlerid
During the execution of the body,
$handlerid
is the id of thewhen
command to which the body belongs. These commands are equivalent:
when X -temp { do_stuff; }
when X { do_stuff; delete $handlerid; }
$booting
$booting
is set totrue
if the event occurs during the boot process. Whenever a new program is debugged, it is first run without the user's knowledge so that the list and location of shared libraries can be ascertained. The process is then killed. This sequence is termed booting.While booting is occurring, all events are still available. Use this variable to distinguish the
sync
and thesyncrtld
events occurring during adebug
and the ones occurring during a normalrun
.Variables Valid for Specific Events
Certain variables are valid only for specific events as shown in the following tables.
TABLE 6-2 Variable Valid for exit
Event$exitcode
Value of the argument passed to _exit(2)
orexit(3)
or the return value ofmain
TABLE 6-3 Variable Valid for dlopen
anddlclose
Events$dlobj
Pathname of the load object dlopened or dlclosed
TABLE 6-4 Variables Valid for sysin
andsysout
Events$syscode
System call number $sysname
System call name
TABLE 6-5 Variable Valid for proc_gone
Events$reason
One of signal, exit, kill, or detach Setting Event Handler Examples
The following are some examples of setting event handlers.
Setting a Watchpoint for Store to an Array Member
To set a watchpoint on
array[99]
, type:
(dbx)
stop access w &array[99]
(2) stop access w &array[99], 4
(dbx)
run
Running: watch.x2
watchpoint array[99] (0x2ca88[4]) at line 22 in file "watch.c"
22 array[i] = i;
Implementing a Simple Trace
To implement a simple trace, type:
(dbx)
when step { echo at line $lineno; }
Enabling a Handler While Within a Function (
in
function)To enable a handler while within a function, type:
<dbx>
trace step -in foo
This is equivalent to:
Determining the Number of Lines Executed
To see how many lines have been executed in a small program, type:
(dbx)
stop step -count infinity
# step and stop when count=inf
(2) stop step -count 0/infinity
(dbx)
run
...
(dbx)
status
(2) stop step -count 133/infinity
The program never stops--the program terminates. The number of lines executed is 133. This process is very slow. It is most useful with breakpoints on functions that are called many times.
Determining the Number of Instructions Executed by a Source Line
To count how many instructions a line of code executes, type:
(dbx) ... # get to the line in question
(dbx)
stop step -instr -count infinity
(dbx)
step ...
(dbx)
status
(3) stop step -count 48/infinity # 48 instructions were executed
If the line you are stepping over makes a function call, the lines in the function are counted as well. You can use the
next
event instead ofstep
to count instructions, excluding called functions.Enabling a Breakpoint After An Event Occurs
Enable a breakpoint only after another event has occurred. For example, if your program begins to execute incorrectly in function
hash
, but only after the 1300'th symbol lookup, you would type:
(dbx)
when in lookup -count 1300 {
stop in hash
hash_bpt=$newhandlerid
when proc_gone -temp { delete $hash_bpt; }
}
Note $newhandlerid
is referring to the just executedstop
in
command.
Resetting Application Files for
replay
If your application processes files that need to be reset during a
replay
, you can write a handler to do that each time you run the program:
Checking Program Status
To see quickly where the program is while it is running, type:
(dbx)
ignore sigint
(dbx)
when sig sigint { where; cancel; }
Then type
^C
to see a stack trace of the program without stopping it.This is basically what the collector hand sample mode does (and more). Use
SIGQUIT (^\)
to interrupt the program because^C
is now used up.Catch Floating Point Exceptions
To catch only specific floating point exceptions, for example, IEEE underflow, type:
(dbx)
ignore FPE
# turn off default handler
(dbx)
help signals | grep FPE
# can't remember the subcode name
...(dbx)
stop sig fpe FPE_FLTUND
...
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |