Examining program data values

Even though you can discover many interesting things about your program by running and stepping through it, you usually need to examine the values of program variables to uncover bugs. For example, it's helpful to know the value of the index variable as you step though a for loop, or the values of the parameters passed in a method call.

When you pause your program while debugging, you can examine the values of variables, parameters, and array items.

Data evaluation occurs at the level of expressions. An expression consists of constants, variables, and values in data structures, combined with language operators. In fact, almost anything you use on the right side of an assignment operator can be used as a debugging expression, except for method calls.

JBuilder has several features enabling you to view the state of your program, which are described in the table below.


Feature Enables...

Thread and stack pane Viewing the methods called and the state of each thread.
Data pane Inspecting data elements (requires compiling with debug information).
Watch pane Watching program values. A watch evaluates an expression according to the current context. If you move to a new context, the expression is re-evaluated for the new context.
Debugger Context Browser window Inspecting the same types of information as the Data pane, Thread and Stack pane, or Watch pane.
Inspector window Inspecting data elements. An inspector is bound to a specific context. Even if you change to a different context, the inspector shows the expression in the original context.
Evaluate/Modify dialog box Evaluating expressions.

Inspecting data elements

You can use an Inspect window to examine and modify data values. Inspect windows are extremely useful because they format the data according to the type of data being viewed. Inspectors are bound to a specific context. Even if you change to a different context, the inspector shows the expression in the original context.

The easiest way to inspect a variable is to right-click the expression you want to inspect in the Data pane, and select Inspect. The expression is always evaluated within the current scope.

You can also inspect data expressions as follows:

  1. Choose Run|Inspect.
    The Inspect dialog box appears.
  2. Type in the expression you want to inspect, or select a previously entered expression from the choice menu, and click OK.
  3. An Inspector window appears.
If the expression you're inspecting is in the scope of the current execution point, the value appears in the Inspector window. If the expression is outside the scope of the execution point, the value is undefined.

If you're inspecting a compound variable, such as an array, you can view the details of the variable by expanding the branches of the tree, or by opening another Inspector window on the element.

You can directly edit the value of a scalar variable by clicking on the value. (A scalar is any single number.)

To inspect an element of a compound variable:

  1. In the Inspector window, select the item you want to inspect.
  2. Right-click, and select Inspect.
To use an Inspector window to change the value of a single variable:
  1. Select the variable whose value you want to modify.
  2. Right-click, and select Modify Value.
  3. Type the new value into the New Value dialog box and click OK.
If you're inspecting an array, there might be so many items displayed that you'll have to scroll in the Inspect window to see all the values. For easier viewing, you can reduce the number of items shown, by using the Adjust Range for Array dialog box.

To open the Adjust Range for Array dialog box:

  1. In the Watch or Data pane, or the Inspect window, right-click an array and select Adjust Range.
  2. Type in the index of the first array element you want to see.
  3. Type in the number of consecutive array elements you want to see.

See also:
Thread and stack pane
Data pane
Watch pane
Source pane for the Debugger

Location of class and instance variable display

Variables can have different scope; there are static variables, instance variables, and local variables. A variable can hold a single value, such as a scalar (a single number), or multiple values, such as an array.

Variables defined by the class are shown in the Data pane. You see them via the this pointer for the class, or via the object of the class that's calling the class. Class variables are shown explicitly at the top of the Data pane, but you must expand a node to see an instance variable.

When you have variables that are defined by the class, when you're looking at the data pane, you see those variables either through the this pointer for the class, or through the object of the class that's calling the class.

Suppose a class contains class variables, some of which are static. Static means they're always available, so they will always be visible in the Data pane. Other variables are not static. A static variable only shows up once, and for every instance of this class, those classes use that same variable. It's like a global variable. There are also instance variables, which are non-static, which means that every instance of the class has its own set of these variables entries in the Data pane.

To access your instance variables in the Data pane, when you are in the class itself, expand the this object in the Data pane. "+ object.this" appears in the Data pane. When you expand that node, you see all of the variables that are the instance variables for that class and that instantiation that you are working through. When you leave the class, you can only access the class through the object that's been declared for that class within the code you're working with. For a variable, such as stream_io variable name = new stream_io, the Data pane will show object variable name. You have to open that object up to see the variables associated with that instance of that object. object variable name contains all the variables that are declared in the class stream_io library.

If you declare multiple objects, you have to open up each one of them individually to see the instance variables associated with that variable.

Watching expressions

Watches enable you to monitor the changing values of variables or expressions during your program run. After you enter a watch expression, the Watch pane displays the current value of the expression. As your program runs, the value of the watch changes as your program updates the values of the variables in the watch expression.

A watch evaluates an expression according to the current context. If you move to a new context, the expression is re-evaluated for the new context. If the execution point moves to a location where any of the variables in the watch expression are undefined, the entire watch expression becomes undefined. If the execution point returns to a location where the watch expression can be evaluated, the Watch pane again displays the current value of the watch expression.

To view the Watch pane, click the Watch tab of the Debugger window.

You can add a watch several ways:

See also:
Watch pane

Editing a watch

To edit a watch expression:

Deleting a watch

To delete a watch expression, select the expression in the Watch pane, then right-click and select Remove Watch. You can also delete all the watches by choosing Remove All Watches from the context menu.

Caution:
The Remove Watch commands cannot be reversed.

Using the Debugger Context Browser as a Debugger pane

The Debugger Context Browser is a window that you can configure like the panes of the Debugger; it's like a floating Debugger pane. You can open multiple instances of the Debugger Context Browser. For most purposes, the recommended window arrangement for using watches while debugging is to use a Debugger Context Browser as a Watch pane, and leave the Debug tab selected in the main Debugger window, rather than selecting the Watch tab.

To open a Debugger Context Browser window, choose View | Debugger Context Browser.

Evaluating and modifying expressions

You can evaluate expressions and change the values of data items using the Evaluate/Modify dialog box. The Evaluate/Modify dialog box has the advantage over watches in that it enables you to change the values of variables during the course of your debugging session. This can be useful if you think you've found the solution to a bug, and you want to try the correction before exiting the Debugger, changing the source code, and recompiling the program.

'i' is an identifier, and can simply be monitored in the Data pane. 'i+2' is a complex expression, for which the Evaluate/Modify dialog box is especially useful.

Evaluating expressions

Select Run|Evaluate/Modify to open the Evaluate/Modify dialog box.

To evaluate an expression, click the Evaluate button at the bottom of the Evaluate/Modify dialog box. Using this dialog box, you can evaluate any valid language expression, except those that contain either:

Specifying a property to view
You cannot set a watch for properties. Though evaluation of properties is not currently supported, in some cases you might be able to evaluate the variable behind the get/set functions of the relevant property.

The Evaluate/Modify dialog box lets you view and modify the values of object properties while running the program. However, to view a property, you need to explicitly specify the property name. For example, you can enter the following expression to evaluate the "bar" property of object "foo":
   foo.bar

You can evaluate string variables, but you cannot modify them in the Evaluate/Modify dialog box.

Changing the display format of expressions
When you evaluate an expression, the current value of the expression is displayed in the Result field of the dialog box. If you need to, you can format the result by adding a comma and one or more format specifiers to the end of the expression entered in the Expression edit box. Valid format specifiers are listed in Expression format specifiers for the Evaluate/Modify dialog box.

Modifying the values of variables

JBuilder enables you to change the values of variables during the course of a debugging session. You can test different error hypotheses and see how a section of code behaves under different circumstances by modifying the value of variables during a debugging session.

When you modify the value of a variable through the Debugger, the modification is effective for that specific program run only; the changes you make through the Evaluate/Modify dialog box do not affect your program source code or the compiled program. To make your change permanent, you must modify your program source code in the Source pane, then recompile your program.

To modify the value of a variable:

  1. Open the Evaluate/Modify dialog box, then enter the name of the variable you want to modify in the Expression edit box.
  2. Click Evaluate to evaluate the variable.
  3. Type a value into the New Value edit box (or select a value from the choice menu), then click Modify to update the variable.

You can change individual variables or elements of arrays, but you cannot change the contents of an entire array.

The expression in the New Value box needs to evaluate to a result that is type-compatible with the variable you want to assign it to. A good rule of thumb is that if the assignment would cause a compile-time or run-time error, it's not a legal modification value.

Expression format specifiers for the Evaluate/Modify dialog box

By default, the Debugger displays the expression in the format that matches the data type of the expression. Integer values, for example, are normally displayed in decimal form. To change the display format, type a comma (,) followed by a format specifier after the expression.

Example
Suppose the Expression box contains the integer value z and you want to display the result in hexadecimal:

  1. In the Expression box, type Z,H.
  2. Click the Evaluate button.
Below is a table of Evaluate/Modify format specifiers.


Character Types affected Method

,C Char, strings Character.  Shows special display characters for ASCII 0..31. By default, such characters are shown using the appropriate C escape sequences (/n, /t, and so on).
,D Integers Decimal.  Shows integer values in decimal form.
,Fn Floating point Floating point.  Shows n significant digits (where n is in the range 2..18, and 7 is the default). For example, to display the first four digits of a floating point value, type ,F4.
,H or ,X Integers Hexadecimal.  Shows integer values in hexadecimal with the 0x prefix.
,R Records, classes, and objects Records/Classes/Objects.  Shows both field names and values such as (X:1;Y:10;Z:5) instead of (1,10,5).
,S Char, strings String.  Shows any non-displayable ASCII characters as #nn, where nn represents the ordinal value of the ASCII character.

For example, to display a result in hexadecimal, type ,H after the expression. To see a floating point number to 3 decimal places, type ,F3 after the expression.