Event Management |
8 |
![]() |
This chapter is organized into the following sections:
Basic Concepts
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 need to be specified.
when event-specification {action; ... } |
Although all event management can be performed through when, dbx has historically had many other commands, which are still retained, either for backward compatibility, or because they are simpler and easier to use.
Creating Event Handlers
The commands when, stop, and trace are used to create event handlers. An event-spec is a specification of an event as documented later in this chapter.
when cond body |
when step -if cond body |
when cond in func body |
when next -if cond -in func body |
These examples illustrate that cond is not a pure event; there is no internal handler for conditions.
when
The when command has a general syntax. When the specified event occurs, the cmds are executed. Once the commands have all executed, the process is automatically continued.
when event-specification [ modifier ] { cmds ... ; } |
stop
The stop command has a general syntax. When the specified event occurs, the process is stopped.
stop event-specification [ modifier ] |
stop is shorthand for a common when idiom:
when event-specification { stop -update; whereami; } |
trace
When the specified event oc
trace event-specification |
curs, a trace message is printed:
Most of the trace commands can be hand-crafted by using the when command, ksh functionality, and event variables. This is especially useful if you want stylized tracing output.
Manipulating Event Handlers
The following list contains commands to manipulate event handlers. For more information on any of the commands, see the section Command Reference at the end of this chapter.
The count limit can be set using the -count modifier. Otherwise, use the handler to individually manipulate event handlers.
handler [ -count | -reset ] hid new-count new-count-limit |
Setting Event Specifications
Event specifiers are used by the stop, when and trace commands to denote event types and parameters. The format is that of a keyword to represent the event type and optional parameters. Event Specifications
The following are event specifications, syntax and descriptions. in func
The function has been entered and the first line is about to be executed. If the -instr modifier is used, it is the first instruction of the function about to be executed. (Do not confuse in func with the -in func modifier.) The func specification can take a formal parameter signature to help with overloaded function names, or template instance specification. For example, you can say:
stop in mumble(int, float, struct Node *) |
at lineno
The designated line is about to be executed. If filename is provided, then the designated line in the specified file is about to be executed. The filename can either be the .o, .c, or .cc name of the file. Although quote marks are not required, they may be necessary if the filename contains odd characters.
at filename:lineno |
Sparc
$o0
Intel
$eax
Power PC
$r3
infunction func
Equivalent to in func for all overloaded functions named func, or all template instantiations thereof. inmember func
inmethod func
Equivalent to in func for the member function named func for every class. inclass classname
Equivalent to in func for all member functions that are members of classname. inobject obj-expr
A member function called on the object denoted by obj-expr has been called. change variable
Fires when the value of variable has changed. cond cond-expr
The condition denoted by cond-expr evaluates to true. Any expression can be used for cond-expr, but it has to evaluate to an integral type. returns
This event is just a breakpoint at the return point of the current visited function. The visited function is used so that you can use the returns event spec after doing a number of up's. The plain return event is always -temp and can only be created in the presence of a live process. returns func
This event fires 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 it through:
when in func { stop returns; } |
step
The step event fires when execution reaches the first instruction of a source line. For example, you can get simple tracing with:
when step { echo $lineno: $line; } |
alias step="when step -temp { whereami; stop; }; cont" |
next
Similar to step except that functions are not stepped into. timer second
Fires when the debugee has been running for seconds. The timer used with this is shared with the collector command. sig sig
When the signal is first delivered to the debugee, this event fires. sig can either be a decimal number or the signal name in upper or lower case; the prefix is optional. This is completely independent of the catch/ignore commands, although the catch command can be implemented as follows:
function simple_catch { when sig $1 { stop; echo Stopped due to $sigstr $sig whereami } } |
Note - When the sig event is received, the process has'nt seen it yet. Only if you cont the process with the given signal is the signal forwarded to it.
sig sig sub-code
When the specified signal with the specified sub-code is first delivered to the child, this event fires. Just as with signals, the sub-code can be entered as a decimal number, in capital or lower case; the prefix is optional. fault fault
This event fires when the specified fault occurs. The faults are architecture dependent, but a set of them is known to dbx as defined by proc (4):
These faults are taken from /sys/fault.h. fault can be any of those listed above, in upper or lower case, with or without the FLT- prefix, or the actual numerical code. Be aware that BPT, TRACE, and BOUNDS are used by dbx to implement breakpoints, single-stepping, and watchpoints. Handling them may interfere with the inner workings of dbx.
modify addr-exp [ , byte-size ]
The specified address range has been modified. This is the general watchpoint facility. The syntax of the event-specification for watchpoints is:
modify addr-exp [, byte-size-exp ] |
stop modify 0x5678, sizeof(Complex) |
Limitations of modify event-spec
Addresses on the stack cannot be watched. sysin code|name
The specified system call has just been initiated and the process has entered kernel mode. sysout code|name
The specified system call is finished and the process is about to return to user mode. sysin | sysout
Without arguments, all system calls are traced. Note that certain dbx features, for example modify event and RTC, cause the child to execute system calls for their own purposes and show up if traced. prog_new
Fired when a new program has been loaded as a result of follow exec.
Note - Handlers for this event are always permanent.
stop
The process has stopped. Whenever the process stops such that the user gets a prompt, particularly in response to a stop handler, this event is fired. For example, the following are equivalent:
display x when stop {print x;} |
sync
The process being debugged has just been exec()'ed. All memory specified in a.out is valid and present but pre-loaded shared libraries have not been loaded yet. For example, printf, although known to dbx, has not been mapped into memory yet. syncrtld
This event is fired after a sync (or attach if the process being debugged has not yet processed shared libraries). It fires after the startup code has executed and the symbol tables of all preloaded shared libraries have been loaded. attach
dbx has successfully attached to a process. detach
The debugee has been detached from. lwp_exit
Fired when lwp has been exited. $lwp contains the id of the exited LWP. proc_gone
Fired when dbx is no longer associated with a debugged process. The predefined variable $reason will be signal, exit, kill, or detach. lastrites
The process being debugged is about to expire. There are only three reasons this can happen:
lib-path is the name of a shared library you are interested in. If it is specified, the event only fires 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 fire whenever there is any dl-activity. $dlobj is empty but $dllist is valid.
If -if is used with a location-based event, like in or at, cond is evaluated in the scope corresponding to that location, otherwise it should be properly qualified with the desired scope.
Counts of all enabled handlers are reset when a program is run or rerun. More specifically, they are reset when the sync event occurs.
Use the delete -temp command to delete all temporary handlers.
when a -temp when a-temp |
In the first example, even though the application might have a variable named temp, the dbx parser resolves the event-spec in favor of -temp being a modifier. In the second example, a-temp is collectively passed to a language specific expression parser and 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 are always valid:
As an example, consider that whereami can be roughly implemented as:
function whereami { echo Stopped in $func at line $lineno in file $(basename $file) echo "$lineno\t$line" } |
Event-Specific Variables
The following event-specific variables are only valid within the body of a when. $handlerid
During the execution of the body, $handlerid is the id of the when command to which the body belongs. These commands are equivalent:
when X -temp { do_stuff; } when X { do_stuff; delete $handlerid; } |
$sig
Signal number that caused the event
$sigstr
Name of $sig
$sigcode
Subcode of $sig if applicable
$sigcodestr
Name of $sigcode
$sigsender
Process id of sender of the signal, if appropriate
$exitcode
Value of the argument passed to _exit(2) or exit(3) or the return value of main
$dlobj
Pathname of the load object dlopened or dlclosed
$syscode
System call number
$sysname
System call name
$reason
One of signal, exit, kill, or detach
$booting
Is set to true if the event occurs during the boot process. Whenever a new program is debugged, it is first booted so that the list and location of shared libraries can be ascertained. The process is then killed. Valid Variables
For Event sig
For Event exit
For Events dlopen and dlclose
For Events sysin and sysout
For Event proc_gone
Examples
Use these examples for setting event handlers. Set Watchpoint for Store to Array Member
To set a watchpoint on array[99]:
(dbx) stop modify &array[99] |
Simple Trace
To implement a simple trace:
(dbx) when step { echo at line $lineno; } |
Enable Handler While Within the Given Function (in func)
For example:
trace step -in foo |
Determine the Number of Lines Executed in a Program
To see how many lines were executed in a small program:
(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. 133 is the number of lines executed. This process is very slow though. This technique is more useful with breakpoints on functions that are called many times.
Determine the Number of Instructions Executed by a Source Line
To count how many instructions a line of code executes:
(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, you end up counting those as well. You can use the next event instead of step to count instructions, excluding called functions.
Enable Breakpoint after Event Occurs
Enable a breakpoint only after another event has fired. Suppose things go bad in function hash, but only after the 1300'th symbol lookup:
(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 executed stop in command.
Set Automatic Breakpoints for dlopen Objects
To have breakpoints in dlopened objects be managed automatically:
(dbx) when dlopen mylib.so { # delete old one if it exists. if [ -n "$B1" ] then delete "$B1" fi # create new one stop in func B1="$newhandlerid" } |
Reset 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 for you each time you run the program:
Check Program Status
To see quickly where the program is while it's running:
(dbx) ignore sigint |
Then type ^C to see a stack trace of the program without stopping it.
Catch Floating Point Exceptions
To catch only specific floating-point exceptions, for example, IEEE underflow:
(dbx)ignore FPE # turn off default handler (dbx) help signals | grep FPE # can't remember the subcode name ... (dbx) stop sig fpe FPE_FLTUND ... |
Command Reference
when
To execute command(s) when line is reached
when at line { command(s); } |
To execute command(s) when proc is called:
when in proc { command(s); } |
stop
To stop execution now and update displays. Whereas normally the process is continued after the body has executed, the stop command prevents that. This form is only valid within the body of a when:
stop -update |
Same as above, but does not update displays:
stop -noupdate |
To stop execution at line line:
stop at line |
To stop execution when function func is called
stop in func |
To set breakpoints on all member functions of a class/struct/union or template class:
stop inclass classname |
To set breakpoints on all member functions:
stop inmember name |
To set breakpoints on all non-member functions:
stop infunction name |
step
The step command is equivalent to:
when step -temp { stop; }; cont |
step -sig $sig |
cancel
Only valid within the body of when. The cancel command cancels any signal that might have been delivered, and lets the process continue. For example:
when sig SIGINT { echo signal info; cancel; } |
status
The status command lists handlers, those created by trace, when, and stop. status hid lists the given handler. If the handler is disabled, its hid is printed inside square brackets [ ] instead of parentheses ( ).
status [-s] -h hid |
The output of status can be redirected to a file. Nominally, the format is unchanged during redirection. You can use the -s flag to produce output that allows a handler to be reinstated using the source command. If the -h option is used, hidden handlers are also listed.
delete
delete hid deletes the specified handler; delete all or delete 0 (zero), and delete -all deletes all handlers including temporary handlers. delete -temp deletes only all temporary handlers.
delete all -all -temp hid [hid ... ] |
-h hid is required if hid is a hidden handler. -h all deletes all hidden handlers as well.
clear
clear with no arguments deletes all handlers based on breakpoints at the location where the process stopped. clear line deletes all handlers based on breakpoints on the given line.
clear line
handler
handler -disable hid disables the specified event; handler -disable all disables all handlers. handler -enable hid enables the specified handler; handler -enable all enables all handlers.
handler [ -disable | -enable ] all hid [...]
handler [ -count | -reset ] hid new-count-limit