United States |
Previous | Contents | Index |
Character strings are implemented in Compaq C as null-terminated ASCII strings (ASCIZ strings). To examine and deposit data in an entire string, use the /ASCIZ qualifier (abbreviated /AZ) so that the debugger can interpret the end of the string properly. You can examine and deposit individual characters in the string using the C array subscripting operators ([ ]). When you examine and deposit individual characters, use the /ASCII qualifier.
Example C-3 shows the Compaq C program STRING.C used in the examples that follow.
Example C-3 Debugging Sample Program STRING.C |
---|
/* STRING.C This program establishes a string to * * demonstrate the access of strings in Compaq C. */ main() { static char *s = "vaxie"; static char **t = &s; } |
The following examples are based on executing STRING.EXE and show the commands used to manipulate C strings.
The EXAMINE/AZ command displays the contents of the character string pointed to by *s and **t :
DBG> step stepped to STRING\main\%LINE 8 8: } DBG> examine/az *s *STRING\main\s: "vaxie" DBG> examine/az **t **STRING\main\t: "vaxie" |
The DEPOSIT/AZ command deposits a new ASCIZ string in the variable pointed to by *s . The EXAMINE/AZ command displays the new contents of the string:
DBG> deposit/az *s = "Compaq C" DBG> examine/az *s, **t *STRING\main\s: "Compaq C" **STRING\main\t: "Compaq C" |
You can use array subscripting to examine individual characters in the string and deposit new ASCII values at specific locations within the string. When accessing individual members of a string, use the /ASCII qualifier. A subsequent EXAMINE/AZ command shows the entire string containing the deposited value:
DBG> examine/ascii s[3] [3]: " " DBG> deposit/ascii s[3] = "-" DBG> examine/az *s, **t *STRING\main\s: "DEC-C" **STRING\main\t: "DEC-C" |
You can examine structures in their entirety or on a member-by-member basis, and deposit data into structures one member at a time.
To reference members of a structure or union, use the usual C syntax for such references. That is, if variable p is a pointer to a structure, you can reference member y of that structure with the expression p ->y . If variable x refers to the base of the storage allocated for a structure, you can refer to a member of that structure with the x.y expression.
The debugger uses the Compaq C type-checking rules that follow to reference members of a structure or union. For example, in the case of x.y , y need not be a member of x ; it is treated as an offset with a type. When such a reference is ambiguous---when there is more than one structure with a member y ---the debugger attempts to resolve the reference according to the rules that follow. The same rules for resolving the ambiguity of a reference to a member of a structure or union apply to both x.y and p ->y .
You can always give a path name with the reference to x to narrow the scope that is used and to resolve the ambiguity. The same path name is used to look up both x and y .
Example C-4 shows the Compaq C program STRUCT.C used in the examples that follow.
Example C-4 Debugging Sample Program STRUCT.C |
---|
/* STRUCT.C This program defines a structure and union * * to demonstrate the access of structures and * * unions in Compaq C. */ main() { static struct { int im; float fm; char cm; unsigned bf : 3; } sv, *p; union { int im; float fm; char cm; } uv; sv.im = -24; sv.fm = 3.0e10; sv.cm = 'a'; sv.bf = 7; /* Binary: 111 */ p = &sv; uv.im = -24; uv.fm = 3.0e10; uv.cm = 'a'; } |
The following examples are based on executing STRUCT.EXE and show the commands used to access structures and unions.
The SHOW SYMBOL command shows the variables contained in the user-defined function main:
DBG> show symbol * in main routine STRUCT\main data STRUCT\main\uv record component STRUCT\main\<generated_name_0002>.im record component STRUCT\main\<generated_name_0002>.fm record component STRUCT\main\<generated_name_0002>.cm type STRUCT\main\<generated_name_0002> data STRUCT\main\p data STRUCT\main\sv record component STRUCT\main\<generated_name_0001>.im record component STRUCT\main\<generated_name_0001>.fm record component STRUCT\main\<generated_name_0001>.cm record component STRUCT\main\<generated_name_0001>.bf type STRUCT\main\<generated_name_0001> |
Set a breakpoint at line 29 and enter a GO command to initialize the variables declared in the structure sv :
DBG> set break %line 29 DBG> go break at STRUCT\main\%LINE 29 29: uv.im = -24; |
Use the EXAMINE command with the name of the structure to display all structure members. Note that sv.cm has the char data type, which is interpreted by the debugger as a byte integer. The debugger also displays the value of bit fields in decimal:
DBG> examine sv STRUCT\main\sv im: -24 fm: 3.0000001E+10 cm: 97 bf: 7 |
To display the ASCII representation of a char data type, use the /ASCII qualifier on the EXAMINE command. To display bit fields in their binary representation, use the /BINARY qualifier:
DBG> examine/ascii sv.cm STRUCT\main\sv.cm: "a" DBG> examine/binary sv.bf STRUCT\main\sv.bf: 111 |
You deposit data into a structure one member at a time. To deposit data into a member of type char , use the /ASCII qualifier and enclose the character in either single or double quotation marks. To deposit a new binary value in a bit field, use the %BIN keyword:
DBG> deposit sv.im = 99 DBG> deposit sv.fm = 3.14 DBG> deposit/ascii sv.cm = 'z' DBG> deposit sv.bf = %BIN 010 DBG> examine sv STRUCT\main\sv im: 99 fm: 3.140000 cm: 122 bf: 2 |
You can also access members of structures (and unions) by pointer, as shown in *p and p ->bf :
DBG> examine *p *STRUCT\main\p im: 99 fm: 3.140000 cm: 122 bf: 2 DBG> examine/binary p ->bf STRUCT\main\p ->bf: 010 |
A union contains only one member at a time, so the value for uv.im is the only valid value returned by the EXAMINE command; the other values are meaningless:
DBG> step stepped to STRUCT\main\%LINE 30 30: uv.fm = 3.0e10; DBG> examine uv STRUCT\main\uv im: -24 fm: -1.5485505E+38 cm: -24 |
This series of STEP and EXAMINE commands shows the content of the union as the different members are assigned values:
DBG> step stepped to STRUCT\main\%LINE 31 31: uv.cm = 'a'; DBG> examine uv.fm STRUCT\main\uv.fm: 3.0000001E+10 DBG> step stepped to STRUCT\main\%LINE 32 33: } DBG> examine/ascii uv.cm STRUCT\main\uv.cm: "a" |
Example C-5 shows the Compaq C program ARSTRUCT.C used in the examples that follow.
Example C-5 Debugging Sample Program ARSTRUCT.C |
---|
/* ARSTRUCT.C This program contains a structure definition * * and a for loop to demonstrate the debugger's * * support for Compaq C operators. */ main() { int count, i = 1; char c = 'A'; struct { int digit; char alpha; } tbl[27], *p; for (count = 0; count <= 26; count++) { tbl[count].digit = i++; tbl[count].alpha = c++; } } |
The following examples are based on executing ARSTRUCT.EXE and show the use of C expressions on the debugger command line.
Relational operators can be used in expressions (such as count == 2 ) in a WHEN clause to set a conditional breakpoint:
DBG> set break %line 20 when (count == 2) DBG> go break at ARSTRUCT\main\%LINE 20 20: } |
The first EVALUATE command that follows uses C syntax to refer to the address of a variable. It is equivalent to the second command, which uses the /ADDRESS qualifier to obtain the address of the variable. The addresses of these variables might not be the same every time you execute the program if you relink the program.
DBG> evaluate &tbl 2146736881 DBG> evaluate/address tbl 2146736881 |
Individual members of an aggregate can be evaluated; the debugger returns the value of the member:
DBG> evaluate tbl[2].digit 3 |
When you perform pointer arithmetic, the debugger displays a message indicating the scale factor that has been applied. It then returns the address resulting from the arithmetic operation. A subsequent EXAMINE command at that address returns the value of the variable:
DBG> evaluate tbl + 4 %DEBUG-I-SCALEADD, pointer addition: scale factor of 5 applied to right argument 2146736901 DBG> examine 2146736901 ARSTRUCT\main\tbl[4].digit: 5 |
The EVALUATE command can perform arithmetic operations on program variables:
DBG> evaluate tbl[4].digit * 2 10 |
The EVALUATE command can also perform arithmetic calculations that may or may not be related to your program. In effect, this command can be used as a calculator that uses C syntax for arithmetic expressions:
DBG> evaluate 7 % 3 1 |
The debugger enters a message when you use an unsupported operator:
DBG> evaluate count++ %DEBUG-W-SIDEFFECT, operators with side effects not supported (++, --) |
Example C-6 shows the Compaq C program POWER.C to be used in the sample debugging session shown in Example C-7.
Example C-6 Debugging Sample Program POWER.C |
---|
/* POWER.C This program contains two functions: "main" and * * "power." The main function passes a number to * * "power", which returns that number raised to the * * second power. */ main() { static int i, j; int power(int); i = 2; j = power(i); } power(int j) { return (j * j); } |
Although this program contains no errors, Example C-7 shows some simple debugger commands that can be used to evaluate its execution. The callout numbers in this sample debugging session are keyed to the notes that follow.
Example C-7 A Sample Debugging Session |
---|
(1) $ CC/DEBUG/NOOPTIMIZE POWER $ LINK/DEBUG POWER $ RUN POWER OpenVMS DEBUG Version 6.n (2) %DEBUG-I-INITIAL, language is C, module set to 'POWER' (3) DBG> set break %LINE 13 (4) DBG> go (5) break at POWER\main\%LINE 13 (6) 13: j = power(i); (7) DBG> step/into (8) stepped to routine POWER\power 16: int j; DBG> step stepped to POWER\power\%LINE 18 18: return (j * j) (9) DBG> examine J (10) %DEBUG-W-NOSYMBOL, symbol 'J' is not in the symbol table DBG> examine j (11) POWER\power\j: 2 DBG> step stepped to POWER\main\%LINE 13+9 13: j = power(i); DBG> step stepped to POWER\main\%LINE 14 14: } DBG> examine j (12) POWER\main\j: 4 DBG> go (13) %DEBUG-I-EXITSTATUS, is '%SYSTEM-S-NORMAL, normal successful completion' (14) DBG> exit $ |
Key to Example C-7:
DBG> |
The OpenVMS Text Processing Utility (TPU) (provided with the OpenVMS operating system) is a high-performance, programmable utility. TPU provides a number of special features, such as multiple buffers and windows, definable keys and key sequences, a procedural language, and a callable interface.
TPU serves as a base on which to layer other text processing applications, for example, text editors. The Extensible VAX Editor (EVE) is the editor provided with TPU. To invoke EVE, enter the following command at the DCL prompt:
$ EDIT/TPU USER.C |
To exit from EVE, press the Do key to get the Command: prompt. If you want to save modifications to your file, enter the EXIT command. If you do not want to save the file or any modification to the file, enter the QUIT command.
For information on TPU and EVE, see the Guide to VMS Text Processing.
C.3 Language-Sensitive Editor and the Source Code Analyzer
The DIGITAL Language-Sensitive Editor (LSE) and the DIGITAL Source Code Analyzer (SCA) must be purchased separately from the OpenVMS operating system. LSE is a text editor intended specifically for software development. SCA is an interactive tool for program analysis.
These products are closely integrated; generally, SCA is invoked through LSE. LSE provides additional editing features that make SCA program analysis more efficient. In addition, LSE and SCA, in conjunction with the Compaq C compiler, provide a set of new enhancements supporting source code design and review.
In addition to text editing features, LSE provides the following software development features:
SCA performs the following types of program analysis:
LSE and SCA together, in conjunction with DIGITAL language compilers, provide the following software design features:
The following sections provide entry, exit, and language-specific information on the combined use of LSE and SCA. For more information on LSE and SCA, see the Guide to Language-Sensitive Editor for VMS Systems and the Guide to Source Code Analyzer for VMS Systems. For more information on CMS, see the Guide to Code Management System for VMS Systems.
Previous | Next | Contents | Index |
|