Debugging a Program With dbx

Stepping Through a Program

dbx supports two basic single-step commands: next and step, plus a variant of step, called step up. Both next and step let the program execute one source line before stopping again.

If the line executed contains a function call, next allows the call to be executed and stops at the following line ("steps over" the call). step stops at the first line in a called function.

step up returns the program to the caller function after you have stepped into a function.

Single Stepping

To single step a specified number of lines of code, use the dbx commands next or step followed by the number of lines [n] of code you want executed:


(dbx) step n

pop pops the top frame off the stack and adjusts the frame pointer and the stack pointer accordingly. The pop command also changes the program counter to the beginning of the source line at the call site.

Continuing a Program

To continue a program, just use the cont command:


(dbx) cont

The cont command has a variant, cont at line_number, which allows you to specify a line other than the current program location line at which to resume program execution. This allows you to skip over one or more lines of code that you know are causing problems, without having to recompile.

To continue a program at a specified line, enter the cont at line_number command in the command pane:


(dbx) cont at 124

The line number is evaluated relative to the file in which the program is stopped; the line number given must be within the scope of the current function.

Using cont at line_number with assign, you can avoid executing a line of code that contains a call to a function that may be incorrectly computing the value of some variable.

To resume program execution at a specific line:

  1. Use assign to give the variable a correct value.

  2. Use cont at line_number to skip the line that contains the function call that would have computed the value incorrectly.

Assume that a program is stopped at line 123. Line 123 calls a function, how_fast() that computes incorrectly a variable, speed. You know what the value of speed should be, so you assign a value to speed. Then you continue program execution at line 124, skipping the call to how_fast().


(dbx) assign speed = 180; cont at 124;

If you use this command with a when breakpoint command, the program skips the call to how_fast() each time the program attempts to execute line 123.


(dbx) when at 123 { assign speed = 180; cont at 124;}

Calling a Function

When a program is stopped, you can call a function using the dbx call command, which accepts values for the parameters that must be passed to the called function.

To call a procedure, type the name of the function and supply its parameters. For eaxample:


(dbx) call change_glyph(1,3)

Notice that while the parameters may be optional, you must type in the parentheses after the function_name, for example:


(dbx) call type_vehicle()

A user may call a function explicitly, using the call command, or implicitly, by evaluating an expression containing function calls or using a conditional modifier such as stop in glyph -if animate().

If the source file in which the function is defined was compiled with the --g flag, or if the prototype declaration is visible at the current scope, dbx checks the number and type of arguments and issues an error message if there is a mismatch. Otherwise, dbx does not check the number of parameters an dproceeds with the call.

By default, after every call command, dbx automatically calls fflush(stdout) to ensure that any information stored in the I/O buffer is printed. To turn off automatic flushing, you can set the dbxenv output_autoflush to off.

For C++, dbx handles the implicit this pointer, default arguments, and function overloading. Automatic resolution of the C++ overloaded functions is done if possible. If any ambiguity remains (for example, functions not compiled with --g), dbx shows a list of the overloaded names.

When you use call, dbx behaves "next-like," returning from the called function. However, if the program hits a breakpoint in the called function, dbx stops the program at the breakpoint and emits a message. If you now issue a where command, the stack trace shows that the call originated from dbx command level.

If you continue execution, the call returns normally. If you attempt to kill, run, rerun, or debug, the command aborts as dbx tries to recover from the this nesting. You can then re-issue the command. Alternatively, you can use the command pop -c to pop all frames up to the most recent call.