Chapter 5. Examining and Changing Data
Prev |  | Next

## Chapter 5. Examining and Changing Data

This chapter describes how to examine and change data in your program while running it under `dbx`. Topics covered include:

- “Using Expressions”

- “Printing Expressions”

- “Using Data Types and Type Coercion (Casts)”

- “Displaying and Changing Program Variables”

- “Determining the Scope of Variables”

- “Displaying Type Declarations”

- “Examining the Stack”

- “Using Interactive Function Calls”

- “C++ Considerations”

## Using Expressions

Many `dbx` commands accept one or more expressions as arguments. Expressions can consist of constants, `dbx` variables, program variables, and operators. This section discusses operators and constants. “Creating and Removing dbx Variables” describes `dbx` variables, and “Displaying and Changing Program Variables” describes program variables.

### Operators

In general, `dbx` recognizes most expression operators from C, Fortran 77, and Pascal. `dbx` also provides some of its own operators. Operators follow the C language precedence. You can also use parentheses to explicitly determine the order of evaluation.

Table 5-1 lists the operators provided by `dbx`.

Table 5-1. `dbx` Language Independent Operators

Operator | Description
--- | ---
`not` | Unary operator returning false if the operand is true
`or` | Binary logical operator returning true if either operand is nonzero
`xor` | Binary operator returning the exclusive-OR of its operands
`/` | Binary division operator (you can also use “`//`” for division)
`div` | Binary operator that coerces its operands to integers before dividing
`mod` | Binary operator returning op1 modulo op2. This is equivalent to the C “`%`” operator
`#` exp | Unary operator returning the address of source line specified by exp
`"` file ```"` `#` exp | Unary operator returning the address of source line specified by exp in the file specified by file
proc `#` exp | Unary operator returning the address of source line specified by exp in the file containing the procedure proc

The `#` operator takes the line number specified by the expression that follows it and returns the address of that source line. If you precede the `#` operator with a filename enclosed in quotation marks, the `#` operator returns the address of the line number in the file you specify. If you precede the `#` operator with the name of a procedure, `dbx` identifies the source file that contains the procedure and returns the address of the line number in that file.

For example, to print the address of line 27 in the current source file, enter:

    (dbx) print #27

To print the address of line 27 in the source file `foo.c` (assuming that `foo.c` contains source that was used to compile the current object file), enter:

    (dbx) print "foo.c" #27

To print the address of line 27 in the source file containing the procedure `bar` (assuming that `bar` is a function in the current object file), enter:

    (dbx) print bar #27

| Note: A pound sign (`#`) introduces a comment in a `dbx` script file. When `dbx` sees a pound sign in a script file, it interprets all characters between the pound sign and the end of the current line as a comment. See “Executing dbx Scripts” for more information on `dbx` script files. To include the `#` operator in a `dbx` script, use two pound signs (for example, `##27`).

Table 5-2 lists the C language operators recognized by `dbx`.

Table 5-2. C Language Operators Recognized by `dbx`

Type | Operators
--- | ---
Unary | `! & + - * sizeof()`
Binary | `% << >> == <= >= != < > & && | || + - * / [ ] -> .`

| Note: C does not allow you to use the `sizeof` operator on bit fields. However, `dbx` allows you to enter expressions using the `sizeof` operator on bit fields; in these cases, `dbx` returns the number of bytes in the data type of bit fields (such as `int` or unsigned `int`). The C language “`^`” exclusive-OR operator is not supported. Use the dbx “`xor`” operator instead.

Table 5-3 lists the Pascal operators`` ``recognized by `dbx`.

Table 5-3. Pascal Operators Recognized by `dbx`

Type | Operators
--- | ---
Unary | `not ^ + -`
Binary | mod = <= >= <> < > and or + - * / div [ ]

Table 5-4 lists the Fortran 77 language operators recognized by `dbx`. Note that `dbx` does not recognize Fortran logical operators (such as `.or.` and `.TRUE.`).

Table 5-4. Fortran 77 Operators Recognized by `dbx`

Type | Operators
--- | ---
Unary | `+ -`
Binary | `+ - * /`

| Note: Fortran array subscripting must use “[]” not “()”. For example, if `x` is a two-dimension Fortran array, `print x(1,2)` won't work; however, `print` `x[1,2]` will work. If an array is defined as a Fortran array, refer to it with the standard Fortran subscript ordering.

### Constants

You can use both numeric and string constants under `dbx`.

| Note: Expressions cannot contain constants defined by `#define` declarations to the C preprocessor.

#### Numeric Constants

In numeric expressions, you can use any valid integer or floating point constants. By default, `dbx` assumes that numeric constants are in decimal. You can set the default input base to octal by setting the `dbx` variable $octin to a nonzero value. You can set the default input base to hexadecimal by setting the `dbx` variable $hexin to a nonzero value. If you set both $octin and $hexin to nonzero values, $hexin takes precedence.

You can override the default input type by prefixing “0x” to indicate a hexadecimal constant, or “0t” to indicate a decimal constant. For example, “0t23” is decimal 23 (which equals hexadecimal 0x17), and “0x2A” is hexadecimal 2A (which equals decimal 42).

By default, `dbx` prints the value of numeric expressions in decimal. You can set the default output base to octal by setting the `dbx` variable $octints to a nonzero value. You can set the default output base to hexadecimal by setting the `dbx` variable $hexints to a nonzero value. If you set both $octints and $hexints to nonzero values, $hexints takes precedence.

#### String Constants

Most `dbx` expressions cannot include string constants. The `print` and `printf` commands are two of the `dbx` commands that accept string constants as arguments. You can also use the ```set` command to assign a string value to a `dbx` variable.

Otherwise, string constants are useful only as arguments to functions that you call interactively. See “Using Interactive Function Calls” for information on interactive function calls.

You can use either the double-quote character (`"`) or the single-quote character (`'`) to quote strings in `dbx`.

In general, `dbx` recognizes the following escape sequences in quoted strings (following the standard C language usage):

    \\ \n \r \f \b \t \' \" \a

## Printing Expressions

`dbx` provides the following commands for printing values of expressions:

`print` [exp1 [`,` exp2`,` ...] ] |  | Prints the value(s) of the specified expression(s).
`printd` [exp1 [`,` exp2`,` ... ] ] |  | Prints the value(s) of the specified expression(s) in decimal. (`pd` is an alias for `printd`. See “Creating and Removing dbx Variables” for more information about `dbx` aliases.)
`printo` [exp1 [`,` exp2`,` ... ] ] |  | Prints the value(s) of the specified expression(s) in octal. (`po` is an alias for `printo`.)
`printx` [exp1 [`,` exp2`,` ... ] ] |  | Prints the value(s) of the specified expression(s) in hexadecimal. (`px` is an alias for `printx`.)

The variable types are listed in Table 5-5.

Table 5-5. Variable Types

Type | Variable Name | Value
--- | --- | ---
signed char | `sc` | 0xff
unsigned char | `usc` | 0xff
signed short | `ssh` | 0xffff
unsigned short | `ush` | 0xffff

Examples include:

    (dbx) pd sc
    -1
    (dbx) pd ssh
    -1
    (dbx) px sc
    0xff
    (dbx) px ssh
    0xffff
    (dbx) pd usc
    255
    (dbx) pd ush
    65535

`dbx` always prints the bits in the appropriate type. `pd` is an exception; it expands signed types with sign extension so the decimal value looks correct.

Another example:

    (dbx) print sc, usc
    '\377' '\377'

If `$hexchars` is set, this command displays `'0xff`' ``0xff`'. (This is a change from releases previous to IRIX 5.2. Previously, the `px`, `po` cases on signed short expanded to 32 bits, so `px sc` printed `0xffffffff`.)

If the printed data type is `pointer`, `dbx` uses the format specified in the `$addrfmt` or `$addrfmt64` predefined `dbx` variable (`$addrfmt64` is used on only 64-bit processes).

`printf` string [`,` exp1 [`,` exp2`,` ... ] ] |  | Print the value(s) of the specified expression(s) in the format specified by the string, string. The `printf` command supports all formats of the IRIX `printf` command except “`%s`.” For a list of formats, see the `printf`(3S) reference page.

## Using Data Types and Type Coercion (Casts)

You can use data types for type conversion (casting) by including the name of the data type in parentheses before the expression you want to cast. For example, to convert a character into an integer, use `(int)` to cast the value:

    (dbx) print (int) 'b'
    98

To convert an integer into a character, use `(char)` to cast the value:

    (dbx) print (char) 67
    'C'

This is standard C language type casting.

## Displaying and Changing Program Variables

You can use the value of program variables in `dbx` expressions. You can also change the value of program variables while running your program under `dbx` control.

### Qualifying Variable Names

You can use the same name for different variables multiple times in the same program. For example, you can use a temporary counter named “i” in many different functions.

During program execution, this potential ambiguity presents no problem. The scope of each variable is local; space is allocated for it when the function is called and freed when the function returns.

Under `dbx`, however, you need to be able to distinguish between different variables that may have the same name. To do so, you can qualify a reference to a variable to specify its scope.

`dbx` qualifies variables with the file (also called module), the procedure, a block, or a structure. You can manually specify the full scope of a variable by separating scopes with periods. For example, in the expression:

    mrx.main.i

i is the variable name, main is a procedure in which it appears, and `mrx` is the source file (omitting the file extension) in which the procedure is defined.

To illustrate, consider a C program called `test` that contains a function `compare`. In this example, the variable i is declared in both the `main` procedure and the `compare` function:

    int compare ( int );

    main( argc, argv )

    int argc;
    char **argv;
    {
       int i;
    ...
    }

    int compare ( arg1, arg2 )
    {
       int i;
    ...
    }

To trace the value of the i that appears in the function `compare`, enter:

    (dbx) trace test.compare.i

To print the value of the i that appears in the procedure `main`, enter:

    (dbx) print test.main.i

A leading dot (a period at the beginning of the identifier) tells `dbx` that the first qualifier is not a module (file).

The leading dot is useful when a file and a procedure have the same name. For instance, suppose `mrx.c` contains a function called `mrx`. Further, suppose that `mrx.c` contains a global variable called mi and a local variable, also called mi. To refer to the global variable, use the qualified form .mrx.mi, and to refer to the local variable, use the qualified form mrx.mrx.mi.

### Variable Scope

You can access the value of a variable only while it is in scope. The variable is in scope only if the block or procedure with which it is associated is active.

After you start your program, whenever your program executes a block or procedure that contains variables, your program allocates space for those variables and they “come into scope.” You may access the values of those variables as long as the block or procedure is active. Once the block or procedure ends, the space for those variables is deallocated and you may no longer access their values.

### Displaying the Value of a Variable

You can display the value of a program variable using the ```print`, ```printd`, ```printf`, ```printo`, and ```printx` commands and the `pd`, `po`, and `px` aliases described in “Printing Expressions”. For example, to print the value of the program variable total, enter:

    (dbx) print total
    235

The `print` command also displays arrays, structures, and other complex data structures. For example, if message is a character array (a string), `dbx` prints the string:

    (dbx) print message
    "Press <Return> to continue."

As a more complex example, consider a simple linked list stored as an array of elements, each element consisting of a pointer to the next element and an integer value. If the array is named list, print the entire array by entering:

    (dbx) print array

`dbx` prints the value of each element in the array:

    {
        [0] struct list {
            next = (nil)
            value = 1034
        }
        [1] struct list {
            next = 0x10012258
            value = 1031
        }
        [2] struct list {
            next = 0x10012270
            value = 1028
        }
        [3] struct list {
            next = 0x10012288
            value = 1025
        }
        [4] struct list {
            next = 0x100122a0
            value = 1022
        }
        [5] struct list {
            next = 0x100122b8
            value = 1019
        }
    ...
    }

To print an individual element, enter a command such as:

    (dbx) print array[5]
    struct list {
        next = 0x100122b8
        value = 1019
    }

No simple method exists for examining a portion of an array with the `print` command. However, if your array consists of simple elements such as integers or floating point values, you can directly examine the contents of memory using the `/` (examine forward) command described in “Examining Memory and Disassembling Code”.

Suppose a single-precision floating point array is named float_vals. To see the six consecutive elements beginning with the fifth element, enter:

    (dbx) &float_vals[4] / 6f
    10012018:  0.25000000000000000 0.20000000298023224 0.16666699945926666
    0.14280000329017639
    10012028:  0.12500000000000000 0.11111100018024445

### Changing the Value of a Variable

The ```assign` command changes the value of existing program variables. You can also use the `assign` command to change the value of machine registers, as described in “Changing Register Values”.

The syntax of the `assign` command is:

`assign` variable `=` expression |  | Assigns the value of expression to the program variable, variable.

For example:

    (dbx) assign x = 27
    27
    (dbx) assign y = 37.5
    37.5

If you receive an `incompatible types` error when you try to assign a value to a pointer, use casts to make the assignment work. For example if next is a pointer to a structure of type “element,” you can assign next a null pointer by entering:

    (dbx) assign *(int *) (&next) = 0
    0
    (dbx) assign next = 0
    (nil)
    (dbx) assign next = (struct list*) 0;
    (nil)

In this example, `nil` denotes that the value of the pointer is 0; `nil` is similar to NULL in the C language.

### Conflicts Between Variable Names and Keywords

When naming variables in your program, avoid using any `dbx` keywords. If you have a variable with the same name as a `dbx` keyword and you attempt to use that variable in a `dbx` command, `dbx` reports a syntax error.

If you do have a program variable with the same name as a `dbx` command, you can force `dbx` to treat it as a variable by enclosing the variable in parentheses. For example, if you try to print the value of a variable named in by entering the following command, `dbx` displays an error.

    (dbx) print in

    print in
          ^ syntax error
    Suggestion: in is a dbx keyword; a revised command is in history.
    Type !16 or !! to execute: print (in)

The correct way to display the value of input is to enter:

    (dbx) print (in)
    34

`dbx` keywords include:

    all    not
    and    or
    at     pgrp
    div    pid
    if     sizeof
    in     to
    mod    xor

By default, `dbx` treats as keywords the following C type keywords:

    signed     struct
    unsigned   union
    short      enum
    long       double
    int        float
    char

However, if your program is not written in C or C++, you may wish to disable these keywords. The `dbx` variable $ctypenames determines whether or not C type keywords are treated as `dbx` keywords. If $ctypenames is set to 1 (the default), then C type keywords are treated as `dbx` keywords; if $ctypenames is set to 0, they are not.

### Case Sensitivity in Variable Names

Whether or not `dbx` is case sensitive when it evaluates program variable names depends on the value of the `dbx` variable $casesense.

If $casesense is 2 (the default), then the language in which the variable was defined is taken into account (for example, C and C++ are case sensitive while Pascal and Fortran are not). If $casesense is 1, case is always checked. If $casesense is 0, case is always ignored. Note that file (module) names are always case sensitive since they represent UNIX filenames.

## Determining the Scope of Variables

The ```which` command allows you to determine the scope of variables. This command is useful for programs that have multiple variables with the same name occurring in different scopes.

The `which` command prints the fully qualified name of the active version of a specified variable. For example, to determine the scope of the variable i, enter:

    (dbx) which i
    .foo.foo2.i

In the example above, the variable i that is currently active is local to the procedure `foo2` that appears in the module `foo` (corresponding to the file `foo.c` in a C language program).

## Displaying Type Declarations

The ``whatis command displays the type declaration for a specified variable or procedure in your program.

For example, to display the type declaration for the variable i, enter:

    (dbx) whatis i
    int i;

The following example illustrates the output of `whatis` for an array of structures:

    (dbx) whatis array
    struct list {
        struct list* next;
        int value;
    } array[12];

When you provide a procedure name to `whatis`, `dbx` reports the type of the value returned by the procedure and the types of all arguments to the procedure:

    (dbx) whatis foo
    int foo(i)
    int i;
    (dbx) whatis main
    int main(argc, argv)
    int argc;
    char** argv;

## Examining the Stack

Each time your program executes a procedure, the information about where in the program the call was made from is saved on a stack. The stack also contains arguments to the procedure and all of the procedure's local variables. Each procedure on the stack defines an activation level. Activation levels can also consist of blocks that define local variables within procedures.

The activation level determines the scope of many `dbx` commands and expressions. For example, unless you qualify a variable, as described in “Qualifying Variable Names” `dbx` assumes that variables you reference are local to the current activation level.

The most recently called procedure or block is numbered 0. The next active procedure (the one that called the current procedure) is numbered 1. The last activation level is always the main program block.

### Printing Stack Traces

The ```where` command prints stack traces. Stack traces show the current activation levels (procedures) of a program.

For example, consider the following stack trace for a program called `test`:

    (dbx) where
    >  0 foo2(i = 5) [“/usr/var/tmp/dbx_examples/test.c”:44, 0x1000109c]
       1 foo(i = 4) [“/usr/var/tmp/dbx_examples/test.c”:38, 0x1000105c]
       2 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test.c”:55, 0x10001104]
       3 __start() [“/shamu/lib/libc/libc_64/crt1text.s”:137, 0x10000ee4]

This program has four activation levels. The most recent, a call of the procedure `foo2`, is numbered 0. The currently selected activation level is 0, indicated by the “>” character.

The stack trace also reports that `foo2` was passed one argument: the value `5` was assigned to the local variable i. The trace indicates that the program was stopped at line 44 of the file `test.c`, which translates to machine address 0x1000109c.

The stack trace reports similar information for the next two activation levels in this example. You can see that the function `foo` called `foo2` from line 38 in `test.c`. In turn, `foo` was called by `main` at line 55 of the file `test.c`. Finally, the run-time start-up level was called at line 137 from the file `ctrltext.s`.

If you compile with `–` `g0` or with no `–` `g` option, limited symbols are reported. In cases such as this, where detailed symbolic information is not available, the four hexadecimal values returned represent `dbx`'s guess that the function has four integer arguments. The following example illustrates such a case:

    (dbx) where
    >  0 fooexample(0x300000000, 0x4000000ff, 0x5000000ff, 0x0) [“/usr/var/tmp/dbx_examples/test3.c”:10, 0x10000cf8]
       1 main(0x3, 0x4, 0x5, 0x0) [“/usr/var/tmp/dbx_examples/test3.c”:5, 0x10000cbc]
       2 __start() [“/shamu/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000c64]
    (dbx) quit
    Process 22582 terminated
    int fooexample(int,int,int);
    int main()
    {
           fooexample(3,4,5);
           return 0;
    }
    int fooexample(int i, int j, int k)
    {
           int x = i + j + 3*k;
           return x;
    }

The examples below show register values from code compiled without a `–` `g` option. MIPS1 or MIPS2 code using the 32-bit ABI (for example, on an Indy):

    (dbx) where
    > 0 subr1(0x3, 0x7fffaf14, 0x7fffaf1c, 0x0) [“t.c”:3, 0x4009ec]
      1 test(0x3, 0x7fffaf14, 0x7fffaf1c, 0x0) [“t.c”:8, 0x400a10]
      2 main(0x1, 0x7fffaf14, 0x7fffaf1c, 0x0) [“t.c”:13, 0x400a48]
      3 __start() [“crt1text.s”:133, 0x40099c]

There are four hexadecimal values displayed in most lines of the code above since the 32-bit MIPS ABI has four integer argument passing registers. No user-useful registers are passed to `__start()`.

MIPS3 or MIPS4 code using the 64-bit ABI (for example, on a Power Challenge):

    (dbx) where
    > 0 subr1(0x3, 0xffffffaed8, 0xffffffaee8, 0x0, 0x2f, 0x10, 0x0, 0xfbd82a0) [“/usr/people/doc/debug/t.c”:3, 0x10000c9c]
      1 test(0x3, 0xffffffaed8, 0xffffffaee8, 0x0, 0x2f, 0x10, 0x0, 0xfbd82a0) [“/usr/people/doc/debug/t.c”:9, 0x10000ce8]
      2 main(0x1000000ff, 0xffffffaed8, 0xffffffaee8, 0x0, 0x2f, 0x10, 0x0, 0xfbd82a0) [“/usr/people/doc/debug/t.c”:14, 0x10000d2c]
      3 __start() [“/shamu/redwood2/work/irix/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000c70]

There are eight hexadecimal values displayed in most lines of the code above since the 64-bit MIPS ABI has eight integer argument passing registers. No user-useful registers are passed to `__start()`.

The values listed as arguments are the integer argument-passing register values. Typically, only the `0` entry of the stack has those argument values correct. Correctness is not guaranteed because the code generator can overwrite the values, using the registers as temporary variables.

The debugger reports the integer argument-passing registers because this information may be of some value.

For example, for the code samples above, the following code calls `subr1()`:

    int test(void)
    {
         subr1(3);
    }

This code displays `0x3` as the argument register value. The other registers listed for `subr1` contain arbitrary data.

### Moving Within the Stack

The ```up` and ```down` commands move up and down the activation levels in the stack. These commands are useful when examining a call from one level to another. You can also move up and down the activation stack with the `func` command described in “Moving to a Specified Procedure”.

The `up` and `down` commands have the following syntax:

`up` [num] |  | Moves up the specified number of activation levels in the stack. The default is one level.
`down` [num] |  | Moves down the specified number of activation levels in the stack. The default is one level.

When you change activation levels, your scope changes. For example, unless you qualify a variable, as described in “Qualifying Variable Names”, `dbx` assumes that variables you reference are local to the current activation level. Also, `dbx` changes the current source file to the file containing the procedure's source.

Consider examining the stack trace for a program called `test4` and moving up in the activation stack:

    (dbx) where
    >  0 foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       1 foo(i = 4) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]
       2 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test4.c”:25, 0x10000fa0]
       3 __start() [“/shamu/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000f34]
    (dbx) print i
    5
    (dbx) up
    foo:  40  r = foo2(i+1);

The current activation level is now the procedure `foo`. As indicated in the output, the variable i receives the argument passed to `foo` and is therefore local to `foo`. The variable i at this activation level is different from the variable i in the `foo2` activation level. You can reference the currently active i as “i”; whereas you must qualify the reference to the i in foo2:

    (dbx) print i
    4
    (dbx) print foo2.i
    <symbol not found>

Moving up one more activation level brings you to the `main` procedure:

    (dbx) up
    main:  25  j = foo(j);
    (dbx) file
    /usr/var/tmp/dbx_examples/test4.c

In this example, the source for `main` is in `test4.c`, whereas the source for `foo` and `foo2` is in `foo.c`; therefore, `dbx` changes the current source file when you move up to the `main` activation level.

`dbx` resets the source file when you return to the `foo2` activation level:

    (dbx) down 2
    foo2:  46  printf(“foo2 arg is %d\n”,i);
    (dbx) file
    /usr/var/tmp/dbx_examples/foo.c

### Moving to a Specified Procedure

The ```func` command moves you up or down the activation stack. You can specify the new activation level by providing either a procedure name or an activation level number.

The syntax for the `func` command is:

`func` {activation_level | procedure} |  | Changes the current activation level. If you specify an activation level by number, `dbx` changes to that activation level. If you specify a procedure, `dbx` changes to the activation level of that procedure. If you specify a procedure name and that procedure has called itself recursively, `dbx` changes to the most recently called instance of that procedure.
`func` |  | Displays the name of the procedure corresponding to the current activation level.

When you change your activation level, your scope changes. For example, unless you qualify a variable as described in “Qualifying Variable Names”, `dbx` assumes that variables you reference are local to the current activation level. Also, `dbx` changes the current source file to the one containing the procedure's source and the current line to the first line of the procedure.

You can also give the `func` command the name of a procedure that is not on the activation stack, even when your program is not executing. In this case, `dbx` has no corresponding activation level to make current. However, `dbx` still changes the current source file to the one containing the procedure's source and the current line to the first line of the procedure.

For example, consider the following activation stack:

    (dbx) where
    >  0 foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       1 foo(i = 4) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]
       2 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test4.c”:25, 0x10000fa0]
       3 __start() [“/shamu/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000f34]

In this case, you can go to the main activation stack by entering:

    (dbx) func main
    main:  25  j = foo(j);

This command changes the current activation level to “2” and changes the current source file to `test4.c`.

If you use the `func` command to go to a function that is not on the activation stack, `dbx` changes only the current source file to the one containing the procedure's source and the current line to the first line of the procedure:

    (dbx) func bar
       3  {
    (dbx) file
    /usr/var/tmp/dbx_examples/bar.c

### Printing Activation Level Information

The ```dump` command prints information about the variables in an activation level:

`dump` |  | Prints information about the variables in the current procedure.
`dump` procedure |  | Prints information about the variables in the specified procedure. The procedure must be active. Starts searching for procedure at the current activation level as set by the `up` or `down` command. (See “Moving Within the Stack” for more information about the `up` and `down` commands.)
`dump .` |  | Prints information about the variables in all procedures in all activation levels.

For example, executing `dump` while in a function called `foo2` appears as:

    (dbx) dump
    foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]

To examine the information for the procedure `main`, enter:

    (dbx) dump main
    main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test4.c”:25,
    0x10000fa0]
    j = 4
    i = 12
    r = <expression or syntax error>
    a = 0
    total = 0

To perform a complete dump of the program's active variables, enter:

    (dbx) dump .
    >  0 foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       1 foo(i = 4) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]
    r = 0
       2 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test4.c”:25, 0x10000fa0]
    j = 4
    i = 12
    r = <bad operand>
    a = 0
    total = 0

## Using Interactive Function Calls

You can interactively call a function in your program from `dbx.`

If the function returns a value, you can use that function in a normal `dbx` expression. For example, consider a function `prime` defined in your program that accepts an integer value as an argument, and returns 1 if the value is prime and 0 if it is not. You can call this function interactively and print the results by entering a command such as:

    (dbx) print prime(7)
    1

### Using ccall

If your function does not return a value, or if you want to execute a function primarily for its side effects, you can execute the function interactively with the `dbx` command `ccall`:

`ccall` func`(`arg1, arg2, ... , argn`)` |  | This command calls a function with the given arguments. Regardless of the language the function was written in, the call is interpreted as if it were written in C, and normal C calling conventions are used.

| Note: Structure and union arguments to a function, and structure and union returns from a function, are not supported.

Functions called interactively honor breakpoints. Thus you can debug a function by setting breakpoints and then calling it interactively.

If you perform a stack trace using the `where` command while stopped in a routine executed interactively, `dbx` displays only those activation levels created by your interactive function call. The activation levels for your active program are effectively invisible. For example, a stack trace looks like this during an interactive function call:

    (dbx) where
    >  0 foo2(i = 9) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       1 foo(i = 8) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]

    ===== interactive function call =====

       2 foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       3 foo(i = 4) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]
       4 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test4.c”:25, 0x10000fa0]
       5 __start() [“/shamu/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000f34]

If you stop execution of an interactively called function, you are responsible for eventually “unstacking” the call and returning from the function call. To unstack a call, you can complete the call using `dbx` commands such as `cont`, `resume`, `next`, or `step` as many times as necessary. If you `run` or `rerun` your program, `dbx` automatically unstacks all interactive function calls.

### Using clearcalls

Another way to unstack an interactive function call is to execute the ```clearcalls` command, which clears all stopped interactive calls.

    (dbx) clearcalls

When stopped or faulted within one or more nested interactive calls, the `clearcalls` command removes these calls from the stack and returns the program to its regular callstack. This command is useful when a segmentation fault, infinite loop, or other fatal error is encountered within the interactive call.

When stopped in an interactive call, the call stack displayed by `where` shows the following line at the end of each stack of interactive call instantiation.

    ==== interactive function call ====

For example, if the procedure `foo()` is interactively called from `main()`, you see the following stack:

    >  0 foo2(i = 9) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       1 foo(i = 8) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]

    ===== interactive function call =====

       2 foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       3 foo(i = 4) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]
       4 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/dbx_examples/test4.c”:25, 0x10000fa0]
       5 __start() [“/shamu/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000f34]

### Nesting Interactive Function Calls

You can also nest interactive function calls. In other words, if you have one or more breakpoints in a function, and you call that function repeatedly, each interactive call is stacked on top of the previous call. Breakpoints in a function affect all nesting levels, so you cannot have different breakpoints at different nesting levels.

The `where` command shows the entire stack trace from which you can determine the nesting depth. The following example has two nesting levels.

    (dbx) where
    >  0 foo2(i = 17) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       1 foo(i = 16) [“/usr/var/tmp/src/dbx_examples/foo.c”:40, 0x100011d4]

    ===== interactive function call =====

       2 foo2(i = 9) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       3 foo(i = 8) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]

    ===== interactive function call =====

       4 foo2(i = 5) [“/usr/var/tmp/dbx_examples/foo.c”:46, 0x10001214]
       5 foo(i = 4) [“/usr/var/tmp/dbx_examples/foo.c”:40, 0x100011d4]
       6 main(argc = 1, argv = 0xffffffad78) [“/usr/var/tmp/src/dbx_examples/test4.c”:25, 0x10000fa0]
       7 __start() [“/shamu/lib/libc/libc_64/csu/crt1text.s”:137, 0x10000f34]

To set a conditional breakpoint, for example, type:

    (dbx) stop in foo if j == 7
    Process     0: [3] stop in foo if j==7

If j is not within the scope of `foo`, then you will receive an error message if you attempt to call `foo` interactively. To prevent this, disable or delete any such breakpoints, conditional commands, or traces before executing the interactive function call.

## C++ Considerations

Debugging a program written in C++ is somewhat different from debugging programs written in other languages. This section describes these differences.

### Accessing C++ Member Variables

Typically you use standard C++ syntax to access member variables of objects. For example, if the string _name is a member variable of the object myWindow, you can print its value by entering:

    (dbx) print myWindow._name
    0x1001dc1c = “MenuWindow”

To display a static member variable for a C++ class, you must specify the variable with the class qualifier. For example, to print the value of the static member variable costPerShare of the class CoOp, enter:

    (dbx) print CoOp::costPerShare
    25.0

### Referring to C++ Functions

For the purpose of `dbx` debugging, functions in C++ programs fall into three general categories:

Member functions |  | Refers to member functions using the syntax classname::functionname. For example, refers to the member function `foo` in the class `Window` as `Window::foo`.
Global C++ functions |  | Refers to global functions using the syntax ::functionname. For example, refers to the global function `foo` as `::foo`.
Non-C++ functions |  | Refers to non-C++ functions using the syntax functionname. For example, refers to the function `printf` as `printf`.

A restriction to keep in mind when using `dbx` with C++ is that you cannot distinguish between overloaded functions. For example, consider two functions:

    print(int);
    print(float);

The following command sets a breakpoint in both functions:

    (dbx) stop in ::print

The following contrived example illustrates various possibilities:

    #include <stdio.h>
    class foo {
       int n;
       public:
       foo() {n = 0;}
       foo(int x);
       int bar();
       int bar(int);
    };

    int foo:: bar()
    {
       return n;
    }

    int foo:: bar(int x)
    {
       return n + x;
    }

    foo::foo(int x)
    {
       n = x;
    }

    int square(int x)
    {
       return x*x;
    }

    main()
    {
       foo a;
       foo b = 11;
       int x = a.bar();
       int y = b.bar(x) + square(x);
       printf("y = %d\n", y);
    }

If you enter:

    (dbx) stop in foo::foo

`dbx` stops execution in the constructor for the variable b; `dbx` may stop in the constructor for the variable `a` (the ability to stop in an inline function may not yet be fully implemented).

If you enter:

    (dbx) stop in foo::bar

`dbx` stops execution both when `a.bar` is called and when `b.bar` is called, because `dbx` is unable to distinguish between the overloaded functions.

To stop in `square`, enter:

    (dbx) stop in ::square

To stop in `printf` (a C function), enter:

    (dbx) stop in printf

Prev | Table of Contents | Next
Chapter 4. Controlling dbx |  | Chapter 6. Controlling Program Execution