6 ACCESSING CODE AND DATA

This chapter contains the following sections:

Introduction
Accessing Variables
Viewing Variables, Structures and Arrays
Changing Variables
The l Command
Expressions
Evaluating Expressions
Monitoring Expressions
Formatting Data
Displaying Memory
Displaying Memory Addresses
Displaying Disassembled Instructions
Intermixed Source and Disassembly
The Stack
How the Stack is Organized
The Stack Window
Listing Locals and Parameters of a Function
Low-level Viewing the Stack
Trace Window
Trace Window Setup
Register Window
Register Window Setup
Editing Registers

6.1 Introduction

This chapter discusses topics related to viewing and editing the variables in your source program and execution environment, including accessing variables and registers, viewing and modifying the data space, using monitors, viewing the source file, and disassembling code.

6.2 Accessing Variables

This section describes how to view and edit your program variables using the debugger. You can monitor data so that every time you stop the program, CrossView Pro updates the current value.

The Data Window displays the values of variables and expressions. As long as the this window is open, CrossView Pro automatically updates the display for each monitored variable and expression each time the program stops.

Uninitialized variables will not have meaningful values when you first start the debugger, since your program's startup code has not been executed.
Also note that global data is initialized at load time. Re-running a program may produce unexpected results. To guarantee that global data is initialized properly, download the program again.

6.2.1 Viewing Variables, Structures and Arrays

You may view variable values, and change them, from the Source Window and the Command Window. CrossView Pro returns the variable in the format var_name = value in the Command Window.

It is possible to display both monitored and unmonitored expressions in the Data Window. After every halt in execution, CrossView Pro updates monitored expressions. Unmonitored expressions are just one-shot inspections of the expressions value. Refer to section 4.6 , CrossView Pro Windows for a detailed description of the Data Window.

To set the default display format of the data shown, select the proper format in the Data | Data Display Setup... dialog.

To show the contents of a variable or to show the type information of a function:

Position the mouse cursor over a variable or a function in the Source Window. A bubble help box appears showing the value of the variable or the type information of the function, respectively.

To evaluate a simple expression:

Double-click on a variable in the Source window. The result of the expression is shown in the Data Window. Alternatively, depending on the preferences you set in the Data Display Setup dialog, the expression appears in the Evaluate Expression dialog. Click the Add Watch or Add Show button to display the result of the expression in the Data Window. Click the Evaluate button to display the result of the expression in the output field of the Evaluate Expression dialog.

To evaluate a complex expression:

From the Data menu, select Evaluate Expression... and type in any C expression in the Evaluate Expression dialog box. Optionally select a display format. Click the Evaluate button.

Type the expression into the command edit field of the Command Window followed by a return or click the Execute button.

For example, to find the value of initval in demo.c type:

and CrossView Pro will display:

FUNCTION: Display the value of a variable.

COMMAND: variable's_name

For variables having the same name as an CrossView Pro command, use /n as format style code.

Any expression that can be typed into the Command Window can also be typed in the Expression field of the Expression Evaluation dialog box. Throughout this discussion, expressions can be typed in either location, depending on what is convenient.

Viewing Structures

You can also view structures.

By using any of the methods described above, you can print out the entire structure. For example:

and CrossView Pro prints out the structure of recordvar and values of recordvar's fields in correct C notation:

Displaying Individual Fields

Similarly, you can instruct the debugger to print the value of an individual field.

In the Source Window, highlight recordvar.color and click the Show Expression button. Or, in the Expression edit field of the Expression Evaluation dialog box or in the Command Window, type the structure name followed by a period and the field name. For instance, to see the field color for the structure recordvar, enter:

Note that CrossView Pro returns the value in the form field_name = value. CrossView Pro also displays enumerated types correctly.

Variables will not have meaningful values when you first start CrossView Pro, since your program's startup code has not been executed.

Displaying the Address of an Array

If you enter the name of an array in the Expression Evaluation dialog box or in the Command Window, the debugger returns its address. For instance, to find the address for the array table, select table from the browse list in the dialog box or type the name in the Command Window:

Note that CrossView Pro returns the address in the form array_name = address.

The debugger can also display the address and value of an individual element of an array. Enter the name of the array and the number of the element in brackets. For instance, to find the address and value of the third element of array table, enter:

Note that CrossView Pro returns the information in the form address = value.

Displaying Character Pointers and Character Arrays

The following piece of C code can be accessed in CrossView Pro using the string format codes:

Sizing Structures

With structured variables, it is especially useful to know the size of a variable.

In the Command Window, you can determine the size of a variable with the sizeof() function. For instance, to determine the size of the structure recordvar, enter:

6.2.2 Changing Variables

With CrossView Pro, you can not only view your variables, but change them. This function allows you to easily test your code by single-stepping through the program and assigning sample values to your variables. For instance, to set the variable initval to 100, enter:

and CrossView Pro confirms initval's new value:

Note that CrossView Pro returns the values of variables with the syntax: var_name = value, with any right-hand side expression evaluated to a single value.

Changing variables in the Data Window

To change a variable in the Data Window, follow these steps:

When in-situ editing is active, you can use the Tab key to move the edit field to the next variable value or use the Shift+Tab key combination to move the edit control to the previous variable.

Assigning Structures

CrossView Pro also allows you to assign whole structures to one another.

You can use a simple equation to assign the structures. For instance, to assign statrec to recordvar, enter:

6.2.3 The l Command

CrossView Pro's windows contain a great deal of information about the current debugging session. Occasionally, however, you have a few closed windows, or wish the information to appear in the Command window (for instance, when you are recording output). Using the l (list) command, you can find out all sorts of things about the current state of the debugger and have the information appear in the Command window.

Arguments of the l Command
a assertions k kernel state data
b breakpoints m memory map (of application code sections)
d directory p procedures (functions)
f files (modules) r registers
g globals s special variables

For configurations that support real-time kernels the l k command can have additional arguments. See the description of the l command in the Command Reference for details.

You may for example view the contents of the registers:

Or the list of procedures (that is, functions):

a complete list of global variables:

The l f command (list files) also shows the address where CrossView Pro placed the first procedure in the module. If the module is a data module then the address reflects the first item's placement.

With all of these l commands you can specify a string:

and CrossView Pro searches the globals for a match with the same initial characters; in this case global variables that begin with record.

6.3 Expressions

6.3.1 Evaluating Expressions

CrossView Pro expressions use standard C syntax, semantics, and allow special variables. You can calculate and show the values of expressions in CrossView Pro by using a variety of methods:

It is possible to display both monitored and unmonitored expressions in the Data Window. CrossView Pro updates monitored expressions after every halt in execution. Unmonitored expressions are just one-shot inspections of the expressions value. Refer to section 4.6 , CrossView Pro Windows for a detailed description of the Data Window.

To evaluate a simple expression:

Double-click on a variable in the Source window. The result of the expression appears in the data window. Alternatively, depending on the preferences you set in the Data Display Setup dialog, the expression appears in the Evaluate Expression dialog. Click the Add Watch or Add Show button to display the result of the expression in the Data Window. Click the Evaluate button to display the result of the expression in the output field of the Evaluate Expression dialog.

To evaluate a complex expression:

From the Data menu, select Evaluate Expression... and type in any C expression in the Evaluate Expression dialog box. Optionally select a display format. Click the Evaluate button.

CrossView Pro calculates the result and displays the value in the appropriate format. For details about expression formats see the section Formatting Expressions in the chapter CrossView Pro Command Language.

Type the expression in the Command Window.

Expressions can contain variable names as arguments. For instance, if the variable initval has a value of 17 and you enter:

CrossView Pro displays:

The expression can contain names of variables, constants, function calls with parameters, and so forth; anything that you can write directly at the Command Window, you can use in the Evaluate Expression dialog box. For more information on expressions and the CrossView Pro command language, refer to the section CrossView Pro Expressions in the Command Language chapter.

The Dot Operand

Using the dot shorthand "." can save you some typing. The dot stands for the last value CrossView Pro displayed. For instance:

Now you can use the value 17 in another expression by typing:

The value is the result of the new expression.

Naturally, using the dot operand saves you from retyping complex expressions.

6.3.2 Monitoring Expressions

CrossView Pro allows you to monitor any variable or expression. Monitoring means that the debugger evaluates a particular expression and displays the result each time the program stops. If you are in window mode, CrossView Pro displays the values of the monitored variables and expressions in the Data window.

Monitor Set Up

To set up a monitor you can:

From the Data menu, select Evaluate Expression... or double-click on a variable in the Source Window, or click on the Watch Expression button to view the Expression Evaluation dialog box. From this dialog box, you can enter an expression and monitor (watch) its value in the Data Window. You can skip the Expression Evaluation dialog if you activate the Bypass Expression Evaluation dialog check box in the Data Display Setup dialog.

Alternatively, click on the New Expression button in the Data Window.

The Data Window must be open to display the result. Otherwise CrossView Pro does not monitor the expression. Therefore, CrossView Pro opens the Data Window automatically when you choose to show or watch an expression.

Type the m expression command in the Command Window.

To place the variable initval in the Data window type:

initval remains in the Data window. You may run the program, step through it, and the display updates continually. Even if you are not in window mode, CrossView Pro still displays the value of initval after every CrossView command.

FUNCTION: Monitor an expression or variable.

COMMAND: m expression

Similarly, if you want twice the value of initval you could type:

And the expression initval*2 is monitored.

Monitored expressions are evaluated exactly as if you had typed them in from the command line; therefore, if you are monitoring a variable, say R, identical to an CrossView Pro command, use the /n format, in this example R/n.

Monitor Delete

To remove a monitored expression you can:

Select the item in the Data Window and click on the Delete Selected Data Item button from the Data Window, or select Data | Delete | Item.

To remove all expressions from the Data Window, select Data | Delete | All.

Type the number m d command in the Command Window.

To remove initval from your Data Window #1, type the number of the expression (first item of the Data Window has number 0) and m d (monitor delete):

and CrossView Pro removes initval (in this case, assuming it is the first variable listed in the window) from the Data Window.

FUNCTION: Remove an expression from the Data Window

COMMAND: number m d

Since local variables have no meaning beyond their range, CrossView Pro issues error messages if you try to evaluate local variables beyond their scope. Some variables also become invisible when the program call another function. For instance, if you are in main(), monitoring sum, and main() calls factorial(), the unqualified name sum is no longer visible inside factorial(). You can get around this problem, however, by monitoring main#sum instead.

6.3.3 Formatting Data

When you display a particular variable, CrossView Pro displays it in the format the symbolic debug information defines for it. You may, however, easily specify another format using dialogues or keyboard commands. See the section Formatting Expressions in the chapter CrossView Pro Command Language.

Examples

To print the value of initval in hexadecimal format, enter

Be sure not to confuse CrossView Pro format codes with C character codes. CrossView Pro uses a / (forward slash) not a \ (backward slash).

Don't worry about trying to memorize the list, you probably won't have occasion to use all these formats. Notice, however, that the /t format code give information about a particular value. For instance, if you wanted to find out what the type of initval is, type:

You can also take more low-level actions, such as finding out which function contains the hexadecimal address 0x100.

CrossView Pro tells you that address 0x100 is in the function main().

6.3.4 Displaying Memory

CrossView Pro supports several methods to display memory contents. The Memory Window provides a very user-friendly yet powerful way to display the raw contents of the target memory.

Refer to section 4.6.4 for a description of the Memory Window.

Format codes also give you control over the number and size of multiple pieces of data to display beginning at a particular address. The debugger accepts format codes in the following form:

Count is the number of times to apply the format style style. Size indicates the number of bytes to be formatted. Both count and size must be numbers, although you may use c (char), s (short), i (int), and l (long) as shorthand for size. Legal integer format sizes are 1, 2, and 4; legal float format sizes are 4 and 8.

For instance:

displays four, hexadecimal two-byte memory locations starting at the address of initval.

With format codes, you may view the contents of memory addresses on the screen. For instance, to dump the contents of an absolute memory address range, you must think of the address being a pointer. To show the memory contents you use the C language indirection operator '*'. Example:

This command displays in hexadecimal two long words at memory location 0x4000 and beyond. Instead of using the size specifier in the display format, you can force the address to be a pointer to unsigned long by casting the value:

To view the first four elements of the array table from the demo.c program, type:

This command displays in decimal the first four 2-byte values beginning at the address of the array table.

By typing the a space followed by a carriage return you can advance and see the succeeding values in the same format:

You may recognize that the array table contains the factorials for the integers 0 through 7.

Displaying memory in this way is particularly effective when you have two-dimensional arrays. In this case you can display each row by specifying the appropriate count. For instance, if myarr is defined as int myarr[5][8]:

displays the values for the eight elements in the first row of myarr. Typing the carriage return repeatedly then display subsequent rows in the same format.

To scroll back in memory, type the ^ (caret) sign:

FUNCTION: Display value(s) at previous memory location.

COMMAND: ^

6.3.5 Displaying Memory Addresses

The f command lets you specify in which notation CrossView Pro displays memory addresses. It takes the same arguments as the printf() function in C.

FUNCTION: Specify memory address notation.

COMMAND: f ["printf-style-format"]

For instance, if you wish to display all memory addresses in octal, type:

Now all addresses appear in octal. To return to the default hexadecimal, type:

Using the f command without an argument also returns to hexadecimal address display.

6.4 Displaying Disassembled Instructions

To show disassembled instructions:

From the View menu, select Source | Disassembly to open the Disassembly Source Window.

Use the /i format switch to display disassembled code in the Command Window.

By using an address and the /i format it is possible to display disassembled code at any point. Suppose you wish to see how the factorial() function has been compiled. One method would be to examine the instructions displayed as you single step through a program at the assembly language level. There is however a quicker method that does not require you to execute the instructions. Type:

This command displays the first ten assembly language instructions of factorial(). Remember that in C a function's name is also its address. Thus factorial is the address of the function factorial().

Note that CrossView Pro keeps track of variable and function names for you in the disassembled code. You can also disassemble from the current execution position by using the program counter:

This command disassembles five assembly language instructions from the current execution line.

You can display disassembled code for any function:

disassembles seven instructions from line 56.

See also the ei command for displaying disassembly in a window.

Labels in Disassembly

To show labels in disassembly:

From the Settings menu, select the Source Window Setup... to open the Source Window Setup dialog box and enable the Symbolic disassembly check box.

Turn the $symbols special variable "ON" by typing the following command in the Command Window:

6.4.1 Intermixed Source and Disassembly

To show intermixed source and disassembly:

From the View menu, select Source | Source and Disassembly to open the Source and Disassembly Window.

Use the /I format switch to display intermixed C and disassembled code in the Command Window.

The /I format works exactly as the /i format, except CrossView Pro intermixes the pseudo-assembly listing with the original C source. This feature is often helpful in displaying long portions of code.

Auto Switch between Source and Disassembly

To automatically switch between source and disassembly window depending on the presence of symbols:

From the Settings menu, select the Source Window Setup... to open the Source Window Setup dialog box.
Enable the Show assembly when SDI is missing check box.

Turn the $autosrc special variable "ON" by typing the following command in the Command Window:

6.5 The Stack

During debugging, you frequently find yourself lost or unable to pinpoint your location through a series of function calls. The stack helps you with the problem by recording the return addresses of all functions you have passed through. CrossView Pro can use this information to reconstruct the path to your current location.

The following diagram shows the structure of the stack.

Figure 6-1: Stack frame layout

6.5.1 How the Stack is Organized

The stack is used for local automatic variables, function parameters and saved registers.

The stack size is defined in the linker control file (tc.i in directory etc) with the macro USTACK, which results in a section called ustack.

The linker defined label __lc_ue_ustack refers to the top of the stack area and is used in the file cstart.asm to initialize the user stack pointer register.

6.5.2 The Stack Window

The Stack Window shows the current contents of the stack after the program has been stopped. This window helps you assess program execution and allows you to view program values. You can also set breakpoints for different stack levels from this window, as described in the chapter Breakpoints and Assertions.

The Stack Window displays the following information for each stack level:

Each stack level shown in the Stack Window is displayed with its level number first. The levels are numbered sequentially from zero. That is, the lowest/last pushed level in the function call graph is always assigned zero.

When you first see stack information, the lowest level appears against a darker background than the other lines in the window. The marked line in the Stack Window is the selected stack level, meaning that this line is selected for window operations. You can change the selected stack level by clicking on a different line.

Checking the Stack from the Command Window

The stack information is also accessible from the Command Window with the t and T commands. The t command reconstructs the program's calling path. For instance, if you stepped into the function factorial() and issue a t (trace) command:

CrossView Pro displays:

The numbers to the left indicate the depth of each function on the stack. The function at the zero stack level is your current function. CrossView Pro tells you the line number where the function was called ([demo.c:line_nr]) and the value of the argument passed (num=value). With this information it is fairly easy to reconstruct your calling path, and see what parameter values your functions have received.

FUNCTION: Trace stack to reconstruct program's calling path.

COMMAND: t

There is a slight variation on the t command called the T command. The two are identical, except that the T command also displays the local variables for each function. For instance:

FUNCTION: Trace stack and display local variables.

COMMAND: T

6.5.3 Listing Locals and Parameters of a Function

As mentioned in the previous section, CrossView Pro displays all parameters of a function. You can view the local variables and parameters of any single function active on the stack To do this:

Follow these steps:

In the Command Window, use the l (lowercase L) command.

For example, assuming you are still in factorial(), issue an l command:

You can accomplish the same task by specifying the stack depth instead of a function name:

6.5.4 Low-level Viewing the Stack

You can directly view the contents of the stack. Although CrossView Pro provides several high level methods of tracing functions on the stack, you can view its contents directly with the frame pointer special variable, $fp . For instance, the command:

displays the four one-byte values in hexadecimal to which the frame pointer points. Notice that the stack frame is not really an array, but by pretending it is, you can display the memory much as you did with the table array. Refer to the Accessing Variables section in this chapter for more information.

6.6 Trace Window

C level trace is not available for all execution environments. Please check the Addendum for details.

The Trace Window displays the most recently executed lines of code each time program execution stops. CrossView Pro automatically updates the Trace Window each time execution halts, as long as the window is open.

For each executed line of code, the Trace Window displays:

6.6.1 Trace Window Setup

The Trace Window's only function is to display the contents of the emulator's/ simulator's trace buffer. The only operation you can perform in this window that directly affects the contents is to set the maximum number of instructions in the display.

To set the displaying limit, select the Initialization tab in the File | Options... dialog. You can change the maximum number of C-Trace machine instructions to fetch from the execution environment's trace buffer and the maximum number of trace output lines in the Trace Window.

To view the most recently executed source statements from the Command Window, use the ct command preceded by the number of machine instructions you want to list. For example, to view the last source lines corresponding to the last ten machine instructions, enter:

FUNCTION: Display in the Command window the most recently executed C statements.

COMMAND: number ct

To activate the source level trace window:

From the View menu, select Trace | Source Level to view the Trace Source Window.

You can view the last machine instructions executed with the ct i command. For example:

displays the last 15 machine instructions in disassembled form in the Command Window.

FUNCTION: Display the most recently executed machine instructions.

COMMAND: number ct i

To activate the instruction level trace window:

From the View menu, select Trace | Instruction Level to view the Trace Instructions Window.

You can view a raw trace with the ct r command. For example:

displays the last 20 trace frames in the Command Window.

FUNCTION: Display a raw trace.

COMMAND: number ct r

To activate the raw trace window:

From the View menu, select Trace | Raw to view the Trace Raw Window.

6.7 Register Window

The Registers Window shows you the values of internal registers on your target processor.

You can create multiple Register Windows and each Registers Window contains the names and contents of all currently selected registers in the selected register set definition. Values are displayed in hexadecimal format. As long as the window is open, the debugger automatically updates the values when the program stops.

To show the list of current registers and their contents in the Command Window, enter the list registers command (l r).

CrossView Pro also supplies the following special variables:

for all targets. For more information, refer to the Command Language chapter.

6.7.1 Register Window Setup

You can configure which register set definition with which (and in which order) registers must be displayed in the Register Window; using the Settings | Register Window Setup... dialog. Since you can have more than one Register Window, the last active Register Window will be configured when you select this menu item.

To configure a Register Window follow these steps:

Once you have selected a register set definition, follow these steps to configure this register set definition:

CrossView Pro automatically updates all Register Windows and places the registers in each Register Window starting at the top-left position on one line, wrapping to the next line if the next register does not fit.

6.7.2 Editing Registers

CrossView Pro lets you change the contents of registers in a simple and direct manner.

Follow these steps:

If the edited value is not acceptable, the debugger will emit an error message and reset the old value.

When in-situ editing is active, you can use the Tab key to move the edit field to the next register value or use the Shift+Tab key combination to move the edit control to the previous register. Use the Esc key to cancel in-situ editing. When a register is not in view the contents of the Register Window will be updated automatically.

You can enter any expression in the Registers Window.

Registers which can be edited symbolically have a special marker just before the register name. You can click on this marker to activate the Assign Register Symbolically dialog.

To access registers from the Command Window, use the $ designation and the register name in the format:


Copyright © 2003 Altium BV