![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Displaying and Changing Data When the debugger has halted program execution, the debugger automatically displays the location in the source code at which execution has halted.
The debugger automatically displays the appropriate language unit and highlights the next statement or declaration that is to be executed or elaborated. The debugger displays the current location in the program being debugged each time execution stops, for example, after a caught exception, a breakpoint, or a stepping operation.
The following is covered in this chapter:
Displaying DataIn the debugger GUI, you can display the current value of a selected object or expression using the Object Display Window (Windows > Object Display) or one of the Show commands. (Debug > Show... and Debug > Show). The current value of an object or expression can also be displayed using the p command.
Using the Debug > Show Command
Selecting the Debug > Show command or Show hot button causes the value of the object under the cursor to be displayed in the Debugger window.
Using the Debug > Show... Command
The Debug > Show... command operates in different ways, depending on whether you issue the command from an editor window or from a debugger window.
When you invoke the Debug > Show... command from an editor window, it displays the current value of any object or expression that is selected. When executed in this way, Debug > Show... takes no parameters. Instead, it uses the current values of the Levels, Expand Pointers, Special Type Display, and Show Location debugger options. (For more about options, see Debugger Options.)
When you issue the Debug > Show... command from a debugger window, it opens the Show Data dialog box. In this dialog box, you can specify an expression whose value you want displayed.
The Object Display Window
The Object Display Window displays and updates the values of expressions in the current execution context. Multiple expressions may be displayed in the window. The value of each expression in the window is preceded by the expression text and an equals sign.
Examples of Object Display Windows for Ada and C/C++ are illustrated in Figure 4.
Figure 4 Object Display Windows for Ada and C/C++
![]()
Adding Objects for Display
An expression can be displayed in the window using one of the following methods:
- 1 . Execute Debug > Show... in an editor window. Enter a debugger expression and turn the In Object Display Window toggle on.
- 2 . Select an object for display, then execute Debug > Object Display in an editor window.
Deleting Objects from the Display
To delete a displayed object, position the cursor on the expression text for the object you wish to delete, and execute the Edit > Delete command. Alternatively select part of the expression text for one or more displayed objects and execute Edit > Delete.
The appearance of a displayed object is governed by the settings of the debugger's display options at the time the object is displayed. The current display options can be viewed and changed by accessing the Display pane of the View > Options dialog. The Display Levels option is not used by the Object Display Window. Instead the window offers expansion and elision features to control how much of a complex object is displayed
Expansion and Elision
The symbol "..." in the Object Display Window indicates that part of the object, or the object pointed to by a pointer, is not being displayed. These elided components can be made visible by expanding them. Components that are already visible may be elided.
The degree of expansion or elision is measured in levels. Expanding by one level shows one more component. For example, expanding an elided record field shows all the field names for the record, and the values for those fields that have simple values. Field values that are records or arrays are not expanded.
The available expand and elide operations are:
Customizing Displays of User-Defined Data Types
Sometimes it is desirable for the debugger to display nonstandard data in special ways. For this purpose, the debugger provides a mechanism called a special type display. With a special type display, you can customize the display of particular objects in accordance with special requirements. For more information, see Debugger Variables and Special Type Display.
Using the p Command
p
Display the value of a variable or expression
Syntax
pexpression
Arguments
- expression
Name of a program variable, subprogram name, task entry name (Ada), or arithmetic expression.
Description
p is the debugger command for displaying the value of program variables or debugger variables and for calling subprograms, task entries (Ada) and functions (C/C++). It evaluates arithmetic expressions that can contain program variables and/or function calls. If the displayed result is an integer, it is displayed in the current output base (default, 10). Change this default with the set obase command.
Name Expressions
For Ada and C/C++ variables, the debugger currently supports simple variable names (MARK, R_A) selected components and expanded names (MARK.LINE), strings (DATE 1..4) and indexed components (X(Y), Z(1,2)). Also, use these in combination (X(M.Z), B.X(1)). The debugger supports the evaluation and display of array slices (for example, p date (1..3)). It evaluates a number of attributes.
Ada and C/C++ subprograms and functions can be called. You can use the results of a function in the expression. Some restrictions exist. For Ada, only parameters of mode in are supported. in out or out parameters are not supported. Default parameter values are not yet supported. Functions returning access values can be called. In addition, functions that return composite types, (e.g., arrays, records) can also be called. Arbitrary return types when the function is not inside of a larger expression are also supported. Only functions that return type String can be used inside a larger expression (and then only if the result is small enough (<= 512 bytes). For example,
p foo()
works for any composite return type, but
p foo() == bar()
works only if foo() and bar() return small strings.
For Ada, a parameterless function must be called using empty parentheses, p foo(). When referencing an Ada or C/C++ subprogram, it may be necessary to resolve overloading.
Ada entry calls can be called. The calls are not made immediately but instead are queued by the debugger task (see Managing Tasks). When the user program is set into motion, the debugger_task spawns a new caller task for each entry call which performs the rendezvous. This allows blocked entry calls to not cause deadlock in the debugged application. Only parameterless entry calls are currently supported.
The debugger uses visibility rules similar —— but not identical —— to Ada or C/C++ for looking up variable names. The current frame determines what names are visible. The visible names are the same names that are visible if a statement is added to the program at the point in the source text corresponding to the current frame.
The p command can be used to display raw memory as described in Memory Location Operations. These facilities can be used to extract memory as a value and use it in an expression. For example,
p (013A770:L) +01A
reads the 32 bits at address 013A770, adds 01A to it, and prints the result.
The p command is also used to display exceptions. Entering the following command prints out the current exception name and a PC value very near to where the exception was raised:
p $exception
This command is useful if you have a set a breakpoint in an exception handler, and there are many places where the exception could have been raised. In addition, if the handler is when others =>, this command helps by displaying the actual name of the exception.
Modifying DataTo modify the value of an object, execute the Debug > Modify Data command in the GUI. Apex opens the Modify Variable dialog box. Modifying data in the Command Pane or non-GUI debugger is done using assignment statements. Using assignment statements is discussed on Modifying Data Using Assignment Statements.
![]()
Expressions
An expression is a formula that defines the computation of a value. The debugger accepts most valid expressions in the Expression field of dialog boxes such as the Modify Variable dialog box. Expressions are evaluated using the programming language grammar rules.
Binary Operators
The debugger performs arithmetic using the following binary operators.
+ = < / AND
- > <= /= OR
* >= **
>+ = < / &&
- > <= != ||
* >= ! ==
The operands to the Ada AND and OR or C/C++ && and || operations must be integer or boolean; floating point operands are not allowed. If both operands to AND or && are non-zero, the result is nonzero. If either or both operands to AND or && are 0, the result is 0. If either or both operands to OR or || are 1, the result is 1. If both operands to OR or || are 0, the result is 0.
Unary Operators
The debugger supports the following unary operators:
+ -
For debugging C, the following unary operators are supported:
& *
The `*' operator dereferences pointers. The fields of a structure are given when the operand is a pointer to a structure.
The value of *'s operand is the address of the memory to access. The operand cannot be a structure, union, float or double data type.
The & unary operator returns the address of its operand. Use the & operator in procedure calls and with variables of any type except registers.
Operands
Operands can be numbers (integers or floating point), program variables or function calls. More than one function call can appear in the same expression. Use functions calls as parameters to other function calls, etc.
In an expression, the debugger implicitly converts an integer number to a floating point number if the integer is one operand of a binary operation (+, -, *, /) and the other operand is a floating point number.
The comparison operators in the following list return an integer value of either 0 (False) or 1 (True).
> <= < >= /= =
> <= < >= != =
Currently, the final value of an expression must have type Integer (Ada) or type Int (C/C++) or type Float. Also, any operand to one of the above operators must be an integer or floating point value. For Ada, Ada access values are currently converted to 32-bit integers.
Attributes (Ada only)
The Apex debugger supports the following predefined Ada attributes. See the Ada LRM for a description of each attribute.
'ADDRESS
'BODY
'FIRST
'FIRST(N)
'LAST
'LAST(N)
'RANGE
'RANGE(N)
'SPECThe following additional attributes (defined by Apex) are also supported:
C++ Scope/Name/Operators
Scope resolution operator
:: <identifier> or :: OPERATOR <operator>The scope resolution operator may be used to refer to a file scope name or operator. This is useful for referencing a name that is hidden or overloaded by a local name or a class member from within a member function.
Qualified names
Multiple inheritance makes it is possible to inherit members from different base classes that have the same name. In this situation:
class_instance.member or class_pointer->member
are ambiguous because member may refer to either of the base classes members.
A qualified name may be used to help resolve this ambiguity.
class_instance.base_class::member
The debugger can resolve all legal C/C++ qualified names and will emit an error message when the class qualification still results in an ambiguity.
Names
Only identifiers, qualified names, and operator function names are recognized as legal names in a C/C++ debugger expression; all other forms are not supported.
Unsupported C/C++ expression forms - Operators
The following operators are not supported in C++ expressions:
++, --, comma, new, delete, ->, ->*, sizeof
All other operators are allowed in debugger expressions.
Modifying Data Using Assignment Statements
Syntax
name := expression address [, number] := expression
Note: := is allowed for assignment in all language contexts. In addition, // is allowed in all language contexts as a comment indicator. This allows multi-language programmers to assign debugger variables and have comments in their ~/.dbrc files, no matter what language the program they are debugging is written in.
Arguments
- address
A number that represents the address of a storage unit in memory. address is represented by a decimal number, a hexadecimal number (with a leading zero) or by an expression.
- expression
A scalar expression or a string. If it is an arithmetic expression, its final value must be of type Integer (Ada) or type Int (C/C++) or type Float.
- name
Any Ada or C/C++ expression that identifies a scalar object or a register name (preceded by a dollar sign). If name is a debugger keyword, precede it with a backslash or it results in a syntax error.
- number
The number of bytes that are modified. If the value of expression is an integer, number must be 1, 2, 3 or 4. If the value of expression is a floating point number, number must be either 4 or 8. [Default: 4]
Description
This command modifies memory. After the memory or register is modified, a line of the form
address: new/old
is printed. address is where the value is written, new is the value that is written, old is the previous value. For variable names, address is not printed.
On cross compilers that support floating point coprocessors, you can assign the coprocessor registers directly. Values assigned in this way are approximations only and the debugger conversion routines are slow at present, particularly for wide-coprocessor registers. The number of bits in the coprocessor registers differ between systems
To modify the value of a register, precede the register name with a dollar sign ($).
Examples
>0200034 := "this is it" >date := "January 5, 1991" >0f7ffeac1,8 := FLOAT_NUM * 3.5 >a.b(3) := 3 >$a0 := 10 ---- modify register a0
>0200034 = "this is it" >date = "January 5, 1991" >0f7ffeac1,8 = FLOAT_NUM * 3.5 >a.b[3] = 3 >$a0 = 10 ---- modify register a0
In Screen Mode
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |