Go to main content
Oracle® Developer Studio 12.6: Debugging a Program with dbx

Exit Print View

Updated: June 2017
 
 

Stepping Through a Program

dbx supports two basic single-step commands: next and step , plus two variants of the step command, called step up and step to. Both the next command and the step command execute one source line before stopping again.

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

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

The step to command attempts to step into a specified function in the current source line, or if no function is specified, into the last function called as determined by the assembly code for the current source line. The function call might not occur due to a conditional branch, or no function might be called in the current source line. In these cases, step to steps over the current source line.

For more information on the next and step commands, see next Command and step Command.

Controlling Single Stepping Behavior

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) next n

or

(dbx) step n

The step_granularity dbxenv variable determines the unit by which the step command and next command step through your code. The unit can be either statement or line.

The step_events environment variable controls whether breakpoints are enabled during a step.

The step_abflow environment variable controls whether dbx stops when it detects that an abnormal control flow change is about to happen. This type of control flow change can be caused by a call to siglongjmp() or longjmp() or an exception throw.

For more information, see Setting dbxenv Variables.

Stepping Into a Specific or Last Function

To step into a function called from the current source code line, use the step to command.

(dbx) step to function 

To step into the last function called:

(dbx) step to

For the following two examples, using step to by itself will step into foo:

foo(bar(baz(4)));
baz()->bar()-> foo()

Continuing Execution of a Program

To continue a program after it has hit a breakpoint or some event, use the cont command.

(dbx) cont

A variant, cont at line-number, enables you to specify a line other than the current program location line at which to resume program execution. This option enables 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, type:

(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 the cont at line-number command with the assign command, you can avoid executing a line of code that contains a call to a function that might be incorrectly computing the value of some variable. To quickly adjust incorrectly computed values, use the assign command to give the variable a correct value. Use cont at line-number to skip the line that contains the function call that would have computed the value incorrectly.

For example, 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 the cont 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 example:

(dbx) call change_glyph(1,3)

While the parameters are optional, you must type the parentheses after the function name. For example:

(dbx) call type_vehicle()

You can 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().

A C++ virtual function can be called like any other function using the print command or call command , or any other command that executes a function call.

For C++, dbx handles the implicit this pointer, default arguments, and function overloading. The C++ overloaded functions are resolved automatically if possible. If any ambiguity remains (for example, functions not compiled with –g), dbx displays a list of the overloaded names.

If the source file in which the function is defined was compiled with the–g option, 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 and proceeds 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 disable automatic flushing, set the dbxenv variable output_auto_flush to off.

When you use the call command, dbx behaves as though you used the next command, returning from the called function. However, if the program encounters a breakpoint in the called function, dbx stops the program at the breakpoint and issues a message. If you then type 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 nesting. You can then reissue the command. Alternatively, you can use the command pop –c to pop all frames up to the most recent call made from the debugger.

Call Safety

Making calls into the process you are debugging, either by using the call command or by printing expressions that contain calls, has the potential for causing severe non-obvious disruptions. For example:

  • A call might go into an infinite loop, which you can interrupt, or cause a segmentation fault. In many cases, you can use a pop –c command to return to the site of the call.

  • When you make a call in a multithreaded application, all threads are resumed in order to avoid deadlocks, so you might see side-effects on threads other than the one on which you made the call.

  • Calls used in breakpoint conditionals might confuse event management (see Resuming Execution).

    Some calls made by dbx are performed safely. If a problem, typically a segmentation fault, is encountered instead of the usual Stopped with call to ..., dbx does one of the following actions:

  • Ignores any stop commands including those caused by detection of memory access errors

  • Automatically issues a pop -c command to return to the site of the call

  • Proceeds with execution

    dbx uses safe calls for the following situations:

  • Calls occurring within an expression printed by the display command. A failed call appears as: ic0->get _data() = <call failed>

    To diagnose such a failure, try printing the expression with the print command.

  • Calls to the db_pretty_print() function, except when the print -p command is used.

  • Calls used in event condition expressions. A condition with a failed call evaluates to false.

  • Calls made to invoke destructors during a pop command.

  • All internal calls.