In dbx, you can perform two types of data checking:
Evaluate data (print). Spot-checks the value of an expression
Display data (display). Monitors the value of an expression each time the program stops
This chapter is organized into the following sections:
This section discusses how to use dbx to evaluate variables and expressions.
If you are not sure which variable dbx is evaluating, use the which command to see the fully qualified name dbx is using.
To see other functions and files in which a variable name is defined, use the whereis command.
For information on the commands, see which Command and whereis Command.
When you want to evaluate or monitor a variable outside the scope of the current function:
Qualify the name of the function. See Qualifying Symbols With Scope Resolution Operators.
or
Visit the function by changing the current function. See Navigating To Code.
An expression should follow current language syntax, with the exception of the meta syntax that dbx introduces to deal with scope and arrays.
To evaluate a variable or expression in native code, type:
print expression |
You can use the print command to evaluate an expression, local variable, or parameter in Java code.
For more information, see print Command.
dbx supports the C++ dynamic_cast and typeid operators. When evaluating expressions with these two operators, dbx makes calls to certain rtti functions made available by the compiler. If the source doesn’t explicitly use the operators, those functions might not have been generated by the compiler, and dbx fails to evaluate the expression.
Pretty-printing lets your program provide its own rendition of an expression's value through a function call. If you specify the -p option to the print command, rprint command, display command, or watch command, dbx searches for a function of the form const chars *db_pretty_print(const T *, int flags, const char *fmt) and calls it, substituting the returned value for print or display.
The value passed in the flags argument of the function is bit-wise or one of the following:
FVERBOSE |
0x1 |
Not currently implemented, always set |
FDYNAMIC |
0x2 |
-d |
FRECURSE |
0x4 |
-r |
FFORMAT |
0x8 |
-f (if set, fmt is the format part) |
FLITERAL |
0x10 |
-l |
The db_pretty_print() function can be either a static member function or a standalone function.
If the dbx environment variable output_pretty_print is set to on, -p is passed to the print command, rprint command, or display command as the default. Use +p to override this behavior.
Consider also the following:
Prior to version 7.6 pretty-printing was based on a ksh implementation of prettyprint. While this ksh function (and its pre-defined alias pp) still exist, most of the semantics have been reimplemented inside dbx with the following results:
For the IDE, the ability of watches, local variables, and balloon evaluation to utilize pretty-printing.
In the print command, display command, and watch command, the -p option uses the native route.
Better scalability, especially now that pretty-printing can be called quite often, especially for watches and local variables.
Better opportunity to derive addresses from expressions.
Better error recovery.
For const/volatile unqualified types, in general, functions such as db_pretty_print(int *, ...() and db_pretty_print(const int *, ...)() are considered distinct. The overload resolution approach of dbx is discerning but non-enforcing:
Discerning. If you have defined variables declared both int and const int, each will be routed to the appropriate function.
Non-enforcing. If you have only one int or const int variable defined, they will match with both functions. This behavior is not specific to pretty-printing and applies to any calls.
Pretty-print functions are invoked for the following:
print -p or if the dbx environment variable output_pretty_print is set to on.
display -p or if the dbx environment variable output_pretty_print is set to on.
watch -p or if the dbx environment variable output_pretty_print is set to on.
Balloon evaluation if the dbx environment variable output_pretty_print is set to on.
Local variable if the dbx environment variable output_pretty_print is set to on.
Pretty-print functions are not invoked for the following:
$[]. The rationale is that $[] is intended to be used in scripts and need to be predictable.
The dump command. dump uses the same simplified formatting as the where command, which may be converted to use pretty-printing in the future. This limitation does not apply to the Local Variables widow in the IDE.
Nested values will not be pretty-printed because dbx does not have the infrastructure to calculate the addresses of nested fields.
The db_pretty_print() must be compiled with the -g option because dbx needs access to parameter signatures.
The db_pretty_print() function is allowed to return NULL.
The main pointer passed to the db_pretty_print() function is guaranteed to be non-NULL but otherwise it may still point to a poorly initialized object.
The dbx environment variable output_pretty_print_fallback is set by default to on, meaning that dbx will fall back on regular formatting if pretty-printing fails. If the environment variable is set to off, dbx will issue an error message if pretty-printing fails.
Pretty-printing might fail for one of these detectable and recoverable reasons:
No pretty-print function found.
The expression to be pretty-printed cannot have its address taken
The function call did not immediately return, which would imply a segmentation fault resulting when the pretty-print function is not robust when encountering bad objects. It could also imply a user breakpoint.
The pretty-print function returned NULL.
The pretty-print function returned a pointer that dbx fails to indirect through.
A core file is being debugged.
For all cases except the function call not immediately returning, the above failures are silent and dbx falls back on regular formatting. But if the output_pretty_print_fallback environment variable is set to off, dbx will issue an error message if pretty-printing fails.
However, if you use the print -p command rather than setting the dbx environment variable output_pretty_print to on, dbx stops in the broken function and allows you to diagnose the cause of failure. You can then use the pop -c command to clean up the call.
The db_pretty_print() function needs to be disambiguated based on the type of its first parameter. In C, you can overload functions by writing them as file statics.
In C++ an object pointer has two types, its static type (what is defined in the source code) and its dynamic type (what an object was before any casts were made to it). dbx can sometimes provide you with the information about the dynamic type of an object.
In general, when an object has a virtual function table (a vtable) in it, dbx can use the information in the vtable to correctly determine an object’s type.
You can use the print command, display command, or watch command with the -r (recursive) option. dbx displays all the data members directly defined by a class and those inherited from a base class.
These commands also take a -d or +d option that toggles the default behavior of the dbx environment variable output_derived_type.
Using the -d flag or setting the dbx environment variable output_dynamic_type to on when there is no process running generates a “program is not active” error message because it is not possible to access dynamic information when there is no process. An “illegal cast on class pointers” error message is generated if you try to find a dynamic type through a virtual inheritance. (Casting from a virtual base class to a derived class is not legal in C++.)
C++ lets you define functions with unnamed arguments. For example:
void tester(int) { }; main(int, char **) { tester(1); }; |
Though you cannot use unnamed arguments elsewhere in a program, the compiler encodes unnamed arguments in a form that lets you evaluate them. The form is as follows, where the compiler assigns an integer to %n:
_ARG%n |
To obtain the name assigned by the compiler, type the whatis command with the function name as its target.
(dbx) whatis tester void tester(int _ARG1); (dbx) whatis main int main(int _ARG1, char **_ARG2); |
For more information, see whatis Command.
To evaluate (or display) an unnamed function argument, type:
(dbx) print _ARG1 _ARG1 = 4 |
When you dereference a pointer, you ask for the contents of the container to which the pointer points.
To dereference a pointer, dbx displays the evaluation in the command pane; in this case, the value pointed to by t:
(dbx) print *t *t = { a = 4 } |
Monitoring the value of an expression each time the program stops is an effective technique for learning how and when a particular expression or variable changes. The display command instructs dbx to monitor one or more specified expressions or variables. Monitoring continues until you turn it off with the undisplay command.
To display the value of a variable or expression each time the program stops, type:
display expression, ... |
You can monitor more than one variable at a time. The display command used with no options prints a list of all expressions being displayed.
For more information, see display Command.
dbx continues to display the value of a variable you are monitoring until you turn off display with the undisplay command. You can turn off the display of a specified expression or turn off the display of all expressions currently being monitored.
To turn off the display of a particular variable or expression, type:
undisplay expression |
To turn off the display of all currently monitored variables, type:
undisplay 0 |
For more information, see undisplay Command.
To assign a value to a variable, type:
assign variable = expression |
You evaluate arrays the same way you evaluate other types of variables.
Here is a sample Fortran array:
integer*4 arr(1:6, 4:7) |
To evaluate the array, use the print command. For example:
(dbx) print arr(2,4) |
The dbx print command lets you evaluate part of a large array. Array evaluation includes:
Array Slicing– Prints any rectangular, n-dimensional box of a multidimensional array.
Array Striding– Prints certain elements only, in a fixed pattern, within the specified slice (which may be an entire array).
You can slice an array, with or without striding. (The default stride value is 1, which means print each element.)
Array slicing is supported in the print, display, and watch commands for C, C++, and Fortran.
For each dimension of an array, the full syntax of the print command to slice the array is:
print array-expression [first-expression .. last-expression : stride-expression] |
where:
Expression that should evaluate to an array or pointer type.
First element to be printed. Defaults to 0.
Last element to be printed. Defaults to upper bound.
Length of the stride (the number of elements skipped is stride-expression-1). Defaults to 1.
The first expression, last expression, and stride expression are optional expressions that should evaluate to integers.
For example:
(dbx) print arr[2..4] arr[2..4] = [2] = 2 [3] = 3 [4] = 4 (dbx) print arr[..2] arr[0..2] = [0] = 0 [1] = 1 [2] = 2 (dbx) print arr[2..6:2] arr[2..6:2] = [2] = 2 [4] = 4 [6] = 6 |
For each dimension of an array, the full syntax of the print command to slice the array is:
print array-expression [first-expression : last-expression : stride-expression] |
where:
Expression that should evaluate to an array type.
First element in a range, also first element to be printed. Defaults to lower bound.
Last element in a range, but might not be the last element to be printed if stride is not equal to 1. Defaults to upper bound.
Length of the stride. Defaults to 1.
The first expression, last expression, and stride expression are optional expressions that should evaluate to integers. For an n-dimensional slice, separate the definition of each slice with a comma.
For example:
(dbx) print arr(2:6) arr(2:6) = (2) 2 (3) 3 (4) 4 (5) 5 (6) 6 (dbx) print arr(2:6:2) arr(2:6:2) = (2) 2 (4) 4 (6) 6 |
To specify rows and columns, type:
demo% f95 -g -silent ShoSli.f demo% dbx a.out Reading symbolic information for a.out (dbx) list 1,12 1 INTEGER*4 a(3,4), col, row 2 DO row = 1,3 3 DO col = 1,4 4 a(row,col) = (row*10) + col 5 END DO 6 END DO 7 DO row = 1, 3 8 WRITE(*,’(4I3)’) (a(row,col),col=1,4) 9 END DO 10 END (dbx) stop at 7 (1) stop at "ShoSli.f":7 (dbx) run Running: a.out stopped in MAIN at line 7 in file "ShoSli.f" 7 DO row = 1, 3 |
To print row 3, type:
(dbx) print a(3:3,1:4) ’ShoSli’MAIN’a(3:3, 1:4) = (3,1) 31 (3,2) 32 (3,3) 33 (3,4) 34 (dbx) |
To print column 4, type:
(dbx) print a(1:3,4:4) ’ShoSli’MAIN’a(1:3, 1:4) = (1,4) 14 (2,4) 24 (3,4) 34 (dbx) |
Here is an example of a two-dimensional, rectangular slice of a C++ array, with the default stride of 1 omitted.
print arr(201:203, 101:105) |
This command prints a block of elements in a large array. Note that the command omits stride-expression, using the default stride value of 1.
As illustrated, the first two expressions (201:203) specify a slice in the first dimension of this two-dimensional array (the three-row column). The slice starts with row 201 and ends with 203. The second set of expressions, separated by a comma from the first, defines the slice for the second dimension. The slice begins with column 101 and ends with column 105.
When you instruct print to stride across a slice of an array, dbx evaluates certain elements in the slice only, skipping over a fixed number of elements between each one it evaluates.
The third expression in the array slicing syntax, stride-expression, specifies the length of the stride. The value of stride-expression specifies the elements to print. The default stride value is 1, meaning: evaluate all of the elements in the specified slices.
Here is the same array used in the previous example of a slice. This time the print command includes a stride of 2 for the slice in the second dimension.
print arr(201:203, 101:105:2) |
As shown in the diagram, a stride of 2 prints every second element, skipping every other element.
For any expression you omit, print takes a default value equal to the declared size of the array. Here are examples showing how to use the shorthand syntax.
For a one-dimensional array, use the following commands:
Prints the entire array with default boundaries.
Prints the entire array with default boundaries and default stride of 1.
Prints the entire array with a stride of stride-expression.
For a two-dimensional array, the following command prints the entire array.
print arr |
To print every third element in the second dimension of a two-dimensional array, type:
print arr (:,::3) |