Chapter 4. Controlling dbx
Prev |  | Next

## Chapter 4. Controlling `dbx`

This chapter describes features of `dbx` that affect its operation while debugging a program. Specifically, this chapter covers:

- “Creating and Removing dbx Variables”

- “Using the History Feature and the History Editor”

- “Creating and Removing dbx Aliases”

- “Recording and Playing Back dbx Input and Output ”

- “Executing dbx Scripts”

## Creating and Removing `dbx` Variables

`dbx` allows you to define variables that you can use within `dbx` to store values. These variables exist entirely in `dbx`; they are not part of your program. You can use `dbx` variables for a variety of purposes while debugging. For example, you can use `dbx` variables as temporary storage, counters, or pointers that you use to step through arrays.

`dbx` also provides many predefined variables that control how various `dbx` commands function. Appendix C, “Predefined dbx Variables”, provides a complete list of predefined `dbx` variables and their purposes.

A `dbx` variable does not have a fixed type. You can assign a `dbx` variable any type of value, even if it already has a value of a different type. However, a variable predefined by `dbx` does have a fixed predefined type.

You can use almost any name for `dbx` variables. A good practice to follow is to use a dollar sign (`$`) as the first character of all `dbx` variables to prevent conflicts with most program variable names. All of `dbx`'s predefined variables begin with a dollar sign.

The commands described in this section apply only to the manipulations of `dbx` variables, not program variables. “Displaying and Changing Program Variables” in Chapter 5, describes how to manipulate program variables.

### Setting `dbx` Variables

The `set` command sets a `dbx` variable to a given value, defining the variable if it does not exist: ``

    set var=exp

This command defines (or redefines) the specified `dbx` variable, setting its value to that of the expression you provide.

If you enter the `set` command without arguments, `dbx` displays (in alphabetical order) a list of all currently defined `dbx` variables, including predefined variables. Partial output looks like this: ``

    (dbx) set
    $addrfmt        “0x%x”
    $addrfmt64      “0x%llx”
    $assignverify   1
    $casesense      2
    $ctypenames     1
    $curevent       3
    $curline        44
    $curpc          268439708
    ...
    $stacktracelimit        1024
    $stdc           0
    $stepintoall    0
    $tagfile        “tags”

You can display the value of a variable by using the `print` command.

Example 4-1. `set` and `print` commands

    (dbx) set $k = 1
    (dbx) print $k
    1
    (dbx) set $k = $k +23
    (dbx) print $k
    24
    (dbx) print $k / 11
    2

In the above example, `dbx` performs an integer division because both the variable `$k` and the constant 11 are integers. If you assign a floating point value to `$k` and evaluate the expression again, `dbx` performs a floating point division:

    (dbx) set $k = 24.0
    (dbx) print $k
    24.0
    (dbx) print $k / 11
    2.1818181818181817

| Note: It is recommended that you begin a `dbx` variable with a `$` to avoid confusion with a program variable. A `dbx` variable without a leading `$` hides any program variable that has the same name. The only way to see the program variable is to remove the `dbx` variable with an `unset` command.

### Removing `dbx` Variables

The `unset` command removes a `dbx` variable.

Example 4-2. `unset` command

For example, to delete the `$k` variable, enter: ``

    (dbx) unset $k

## Using the History Feature and the History Editor

The `dbx` history feature is similar to the C shell's history feature; you can repeat commands that you have entered previously using this command. However, unlike the C shell's history feature, `dbx` does not allow you to execute a history command anywhere except at the beginning of a line. Also, `dbx` does not support history substitution of command arguments such as the C shell `!$` argument.

### Examining the History List

`dbx` stores all commands that you enter in the history list. The value of the `dbx` $lines variable determines how many commands are stored in the history list. The default value is 100.

You can display the history list by using the `history` command.

Example 4-3. `history` command

After setting a breakpoint, running a program, and examining some variables, your history list might look something like this: ``

    (dbx) history
      1     set $prompt = “(dbx)”
      2     set $page=0
      3     set $pimode=1
      4     stop in main
      5     history

### Repeating Commands

You can execute any of the commands contained in the history list. Each history command begins with an exclamation point (`!`). The following list describes `history` command usage:

- `!!`: repeats the previous command. If the value of the `dbx` $repeatmode variable is set to 1, then entering a carriage return at an empty line is equivalent to executing `!!`. By default, $repeatmode is set to 0.``

- `! string`: repeats the most recent command that starts with the specified string .``

- `! integer`: repeats the command associated with the specified integer in the history list.``

- `!- integer`: repeats the command that occurred integer times before the most recent command. Entering `!-1` executes the previous command, `!-2` the command before that, and so forth.``

Example 4-4. `!!` command

You can use the `!!` command to help you single-step through your program. (Single-stepping is described in “Stepping through Your Program” in Chapter 6.) The following illustrates using the `next` command to execute 5 lines of source code and then using the `!!` command to repeat the `next` command.

For example:

    (dbx) next 5
    Process 22545 (test) stopped at [main:60 ,0x10001150]
      60  total += j;
    (dbx) !!
    (!! = next 5)
    Process 22545 (test) stopped at [main:65 ,0x100011a0]
      65  printf(“i = %d, j = %d, total = %d\n”,i,j,total);

Example 4-5. ! string command

Another easy way to repeat a commonly used command is with `! string`. For example, suppose that you occasionally print the values of certain variables using the `printf` command while running your program under `dbx` (the `printf` command is described in “Printing Expressions” in Chapter 5.) In this case, as long as you do not enter any command beginning with `pr` after you enter the `printf` command, you can repeat the `printf` command by entering `!pr`. For example:

    (dbx) printf "i = %d, j = %d, total = %d\n", i, j, total
    i = 4, j = 25, total = 1
      ...
    (dbx) !pr
    i = 12, j = 272, total = 529

Example 4-6. ! integer command

Using `! integer`, you can repeat any command in the history list. If you want to repeat the `printf` command, but you have entered a subsequent `print` command, examine the history list and then explicitly repeat the `printf` command using its reference number. For example:

    (dbx) history
      1     set $prompt = “(dbx)”
      2     set $page=0
      ..
      45    printf "i = %d, j = %d, total = %d\n", i, j, total
      46    next
      ..
      49    print j
      ..
      53    history
    (dbx) !45
    (!45 = printf "i = %d, j = %d, total = %d\n", i, j, total)
    i = 9, j = 43, total = 1084

### The History Editor

The history editor (`hed`) lets you use your favorite editor on any or all of the commands in the current `dbx` history list. When you enter the `hed` command, `dbx` copies all or part of the history list into a temporary file that you can edit. When you quit the editor, any commands left in this temporary file are automatically executed by `dbx`. ``

If you have set the `dbx` $editor variable to the name of an editor, the `hed` command invokes that editor. If you have not set this variable, `dbx` checks if the `EDITOR` environment variable is set, and if so, invokes that editor. If neither the `dbx` variable or the environment variable is set, `dbx` invokes the `vi` editor.

The syntax for the `hed` commands is:

    hed [num1] [
    num1, num2 ] [
    all]

The following arguments are available:

- `hed` (with no arguments): edits only the last line of the history list (the last command executed).

- num1: edits line num1 in the history list.

- num1, num2: edits the lines in the history list from num1 through num2.

- `all`: edits the entire history list.

By default, `dbx` does not display the commands that it executes as a result of the `hed` command when the `dbx $pimode` variable is set to 0. If $pimode is set to 1, `dbx` displays the commands as it executes them. See Appendix C, “Predefined dbx Variables”, for more information.

## Creating and Removing `dbx` Aliases

You can create `dbx` aliases for debugger commands. Use these aliases as you would any other `dbx` command. When `dbx` encounters an alias, it expands the alias using the definition you provided.

`dbx` has a group of predefined aliases that you can modify or delete. These aliases are listed and described in Appendix B, “Predefined Aliases”.

If you find that you often create the same aliases in your debugging sessions, you can include their definitions in your `.dbxinit` file so that they are automatically defined for you. See “Automatically Executing Commands on Startup” in Chapter 2, for more information on the `.dbxinit` file.

### Creating Command Aliases

You can use the `alias` command to define new aliases: ``

    alias name [command
    ] ["string"] [
    arg1 ,...argN "string
    "]

The following arguments are available:

- command: defines name as an alias for command.

- string: defines name as an alias for the quoted string. With this form of the `alias` command, you can provide command arguments in the alias definition.

- [arg1 ,... argN] “string“: defines name as an alias for the quoted string. arg1 through argN are arguments to the alias, appearing in the string definition. When you use the alias, you must provide values for the arguments, which `dbx` then substitutes in string.

The simplest form of an alias is to redefine a `dbx` command with a short alias. Many of the predefined `dbx` aliases fall into this category: for example, `a` is an alias for the `assign` command and `s` is an alias for the `step` command. When you use one of these aliases, `dbx` simply replaces it with the command for which it is an alias. Any arguments that you include on the command line are passed to the command.

Example 4-7. Creating and using aliases

If you want to create `gf` as an alias for the `givenfile` command, enter:

    (dbx) alias gf givenfile
    (dbx) alias gf
    "givenfile"
    (dbx) gf
    Current givenfile is test
    (dbx) gf test2
    Process 22545 (test) terminated
    Executable /usr/var/tmp/dbx_examples/test2
    (dbx) gf
    Current givenfile is test2

More complex alias definitions require more than the name of a command. In these cases, you must enclose the entire alias definition string in double quotation marks. For example, you can define a brief alias to print the value of a variable that you commonly examine. Note that you must use the escape character (`\`) to include the double quotation marks as part of the alias definition. For example:

    (dbx) alias pa "print \"a =\", a"
    (dbx) alias pa
    "print "a =", a"
    (dbx) pa
    a = 3

You can also define an alias so that you can pass arguments to it, much in the same way that you can provide arguments in a C language macro definition. When you use the alias, you must include the arguments. `dbx` then substitutes the values that you provide in the alias definition.

Consider the following alias definition:

    (dbx) alias p(arg1, arg2, arg3, arg4) "print '|arg1|arg2|arg3|arg4|'"
    (dbx) alias p
    (arg1, arg2, arg3, arg4)"print '|arg1|arg2|arg3|arg4|'"

The `p` alias takes four arguments and prints them surrounded by vertical bars (|). For example:

    (dbx) p(1,2,3,4)
    |1|2|3|4|
    (dbx) p( first, second, 3rd,4)
    | first| second| 3rd|4|

In the previous example, `dbx` retains any spaces that you enter when calling an alias.

You can also omit arguments when calling an alias as long as you include the commas as argument separators in the alias call:

    (dbx) p(a,,b,c)
    |a||b|c|
    (dbx) p(,first missing, preceding space,)
    ||first missing| preceding space||
    (dbx) delete
    delete

Example 4-8. Linked lists, aliases, and casts

One way to follow linked lists is to use aliases and casts, another is to use the `duel` command ( see “Using the High-Level Debugging Language duel” in Chapter 5 for more information). This example shows how to construct an alias that follows a simple linked list with members defined by the following structure:

    struct list { struct list *next; int value; };

In this example, a `dbx` variable called $p is used as a pointer to a member of the linked list. You can define an alias called `foll` to print the contents of the list member to which $p currently points and then advance to the next list member. Because the command is too long to fit onto one line, this example uses the backslash character (`\```) to continue the command on a second line:

    (dbx) alias foll "print *(struct list *)$p ; \
    set $p = (long)((struct list *)($p))->next"

Casting $p to an integer type when following the link (the second assignment in the alias) is essential. If omitted, `dbx` may leave the $p reference symbolic and if so, goes into an infinite loop. (Type `Ctrl-c` to interrupt `dbx` if it gets into the infinite loop.)

Before using this alias, you must set $p to point at the first list member. In this example, assume that the program variable top points to the first list member. Then you can use the `foll` alias to follow the linked list, printing the contents of each member as you proceed:

    (dbx) set $p = top
    (dbx) foll
    struct list {
        next = 0x7fffc71c
        value = 57
    }
    (dbx) foll
    struct list {
        next = 0x7fffc724
        value = 3
    }
    (dbx) foll
    struct list {
        next = 0x7fffc72c
        value = 12
    }

### Listing Aliases

You can display the definition of aliases using the `alias` command: ``

    alias [name]

The following arguments are available:

- `alias` (with no arguments): lists all existing aliases.

- name: lists the alias definition for name.

Example 4-9. Listing aliases

To display the definitions of the predefined aliases `l` and `bp`, enter:

    (dbx) alias l
    "list"
    (dbx) alias bp
    "stop in"

### Removing Aliases

The `unalias` command removes the alias you provide as an argument.

Example 4-10. Removing aliases

To remove the `pa` alias defined in Example 4-7, enter the following command: ``

    (dbx) unalias pa

You can remove any of the predefined `dbx` aliases; however, these aliases are restored the next time you start `dbx`.

## Recording and Playing Back `dbx` Input and Output

`dbx` allows you to play back your input and record `dbx`'s output. `dbx` saves the information that you capture in files, which allows you to create command scripts that you can use in subsequent `dbx` sessions.

### Recording Input

Use the `record input` command to start an input recording session. Once you start an input recording session, all commands to `dbx` are copied to the specified file. If the specified file already exists, `dbx` appends the input to the existing file. You can start and run as many simultaneous `dbx` input recording sessions as you need.``

Each recording session is assigned a number when you begin it. Use this number to reference the recording session with the `unrecord` command described in “Ending a Recording Session”.

After you end the input recording session, use the command file with the `playback` `input` or `pi` commands to execute again all the commands saved to the file. See “Playing Back Input”, for details.

Example 4-11. Recording input

To save the recorded input in a file called `script`, enter the following command:

    (dbx) record input script
    [4] record input script (0 lines)

If you do not specify a file to `record input`, `dbx` creates a temporary `dbx` file in the `/tmp` directory. The name of the temporary file is stored in the `dbx` $defaultin variable . You can display the temporary filename by using the `print` command:

    (dbx) print $defaultin

Because the `dbx` temporary files are deleted at the end of the `dbx` session, use the temporary file to repeat previously executed `dbx` commands in the current debugging session only. If you need a command file for use in subsequent `dbx` sessions, you must specify the filename when you invoke `record input`. If the specified file exists, the new input is appended to the file.

### Ending a Recording Session

To end input or output recording sessions, use the `unrecord` command. ``

The following is the syntax of this command:

    unrecord session1 [,
    session2...] [all]

The following arguments are available:

- `session1,[ session2]`: turns off the specified recording session(s) and closes the file(s) involved.

- `all`: turns off all recording sessions and closes all files involved.

Example 4-12. Ending a recording session

To stop recording session 4, enter the following `dbx` command:

    (dbx) unrecord 4

To stop all recording sessions, enter:

    (dbx) unrecord all

The `dbx status` command does not report on recording sessions. To see if any active recording sessions exist, use the `record` command described in “Examining the Record State”.

### Playing Back Input

Use the `playback input` command to execute commands that you recorded with the `record input` command. Two aliases exist for the `playback input` command: `pi` and `source`. If you do not specify a filename, `dbx` uses the current temporary file that it created for the `record input` command.

If you set the `dbx` $pimode variable to nonzero, commands are printed out as they are played back. By default, $pimode is set to zero.

### Recording Output

Use the `record output` command to start output recording sessions within `dbx`. During an output recording session, `dbx` copies its screen output to a file. If the specified file already exists, `dbx` appends to the existing file. You can start and run as many simultaneous `dbx` output recording sessions as you need. ``

By default, the commands you enter are not copied to the output file; however, if you set the `dbx` $rimode variable to a nonzero value, `dbx` also copies the commands you enter.

Each recording session is assigned a number when you begin it. Use this number to reference the recording session with the `unrecord` command described in “Ending a Recording Session”.

The `record output` command is very useful when the screen output is too large for a single screen (for example, when printing a large structure). Within `dbx`, you can use the `playback output` command (described in “Playing Output”) to look at the recorded information. After quitting `dbx`, you can review the output file using any IRIX system text viewing command (such as `vi(1)`).

Example 4-13. Recording output

To record the `dbx` output in a file called `gaffa`, enter:

    (dbx) record output gaffa

To record both the commands and the output, enter:

    (dbx) set $rimode=1
    (dbx) record output gaffa

If you omit the filename, `dbx` saves the recorded output in a temporary file in `/tmp`. The temporary file is deleted at the end of the `dbx` session. To save output for use after the `dbx` session, you must specify the filename when giving the `record output` command. The name of the temporary file is stored in the `dbx` variable $defaultout.

To display the temporary filename, type:

    (dbx) print $defaultout

### Playing Output

The `playback output` command displays output saved with the `record output` command. This command works the same as the `cat(1)` command. If you do not specify a filename, `dbx` uses the current temporary file created for the `record output` command.

Example 4-14. Playing output

For example,t o display the output stored in the file `script` , enter:

    (dbx) playback output script

### Examining the Record State

The `record` command displays all `record input` and `record output` sessions currently active.

Example 4-15. Examining the record state

The following is an example of the `record` command used to display the record sessions:

    (dbx) record
    [4] record input /usr/demo/script (12 lines)
    [5] record output /tmp/dbxoXa17992 (5 lines)

## Executing `dbx` Scripts

You can create `dbx` command scripts by using an external editor and then executing these scripts by using the `pi` or `playback input` command. This is a convenient method for creating and executing automated test scripts.

You can include comments in your command scripts by using a pound sign (`#`) to introduce a comment. To include a `#` operator (described in “Operators” in Chapter 5) in a `dbx` script, use two pound signs (for example, `##27`). 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.

Prev | Table of Contents | Next
Chapter 3. Examining Source Files |  | Chapter 5. Examining and Changing Data