Chapter 1. Getting Started with dbx
Prev |  | Next

## Chapter 1. Getting Started with `dbx`

You can use `dbx` to trace problems in a program at the source code level, rather than at the machine code level. `dbx` enables you to control a program's execution, symbolically monitoring program control flow, variables, and memory locations. You can also use `dbx` to trace the logic and flow of control to acquaint yourself with a program written by someone else.

This chapter introduces some basic `dbx` commands and discusses some tips about how to approach a debugging session. Specifically, this chapter covers:

- “Examining Core Dumps to Determine Cause of Failure”.

- “Debugging Your Programs”.

- “Studying a New Program”.

- “Avoiding Common Pitfalls”.

## Examining Core Dumps to Determine Cause of Failure

Even if your program compiles successfully, it still can crash when you try to run it. When a program crashes, it generates a terminating signal that instructs the system to write out to a `core` file. The `core` file is the memory image of the program at the time it crashed.

You can examine the `core` file with `dbx` to determine at what point your program crashed. To determine the point of failure, follow these steps:

Procedure 1-1. Examining a `core` File

1. If the `core` file is not in the current directory, specify the pathname of the `core` file on the `dbx` command line.

   If the source code for the program is on a different machine or the source was moved, provide `dbx` with the pathname to search for source code (also see “Specifying Source Directories” in Chapter 3).

2. Invoke `dbx` for the failed program as described in “Invoking dbx” in Chapter 2. `dbx` automatically reads in the local `core` file.

3. Perform a stack trace using the `where` command (described in “Examining the Stack” in Chapter 5) to locate the failure point.

For example, suppose you examine the `core` file for a program called `test`. Suppose the stack trace appears as follows:

    (dbx) where

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

In this case, `test` crashed at line 44 of the source file `test.c`. The program crashed while executing the function `foo2`. `foo2` was called from line 38 in the function `foo`, which was in turn called from line 55 in the function `main`. You can use the other features of `dbx` to examine values of program variables and otherwise investigate why `test` crashed.

If you use `dbx` to debug code that was not compiled with the `-g` option, local variables are invisible to `dbx`, and source lines may appear to jump around as a result of various optimizations. If the code is stripped of its debugging information, `dbx` displays very little information.

## Debugging Your Programs

Debugging a program consists primarily of stopping your program under certain conditions and then examining the state of the program stack and the values stored in program variables.

You stop execution of your program by setting breakpoints in your program. Breakpoints can be unconditional , in which case they always stop your program when encountered, or conditional, in which case they stop your program only if a test condition that you specify is true. (See “Setting Breakpoints” in Chapter 6, for more information.)

To use breakpoints to debug your program, examine your program carefully to determine where problems are likely to occur, and set breakpoints in these problem areas. If your program crashes, first determine which line causes it to crash, then set a breakpoint just before that line.

You can use several `dbx` commands to trace a variable's value. Here's a simple method for tracing a program variable:

Procedure 1-2. Tracing program variables

1. Use the `stop` command (see “Setting Breakpoints” in Chapter 6) to set breakpoints in the program at locations where you want to examine the state of the program stack or the values stored in program variables.

2. Use the `run` or `rerun` command (described in “Running Your Program (run, rerun, and sort)” in Chapter 2) to run your program under dbx. The program stops at the first breakpoint that it encounters during execution.

3. Examine the program variable as described in “Displaying the Value of a Variable” in Chapter 5. Examine the program stack as described in “Examining the Stack” in Chapter 5.

4. Use the `cont` command (see “Continuing Execution after a Breakpoint” in Chapter 6) to continue execution past a breakpoint. However, you cannot continue execution past a line that crashes the program.

## Studying a New Program

Use `dbx` to examine the flow of control in a program. When studying the flow of control within a program, use the `dbx` commands `stop`, `run`/`rerun`, `print`, `next`, `step`, and `cont`. Use the following procedure to study a new program.

Procedure 1-3. Studying a new program

1. Use the `stop` command to set breakpoints in the program. When you execute the program under `dbx`, it stops execution at the breakpoints.

   If you want to review every line in the program, set a breakpoint on the first executable line. If you don't want to look at each line, set breakpoints just before the sections you intend to review.

2. Use the `run` and `rerun` commands to run the program under `dbx`. The program stops at the first breakpoint.

3. Use the `print` command to print the value of a program variable at a breakpoint.

4. Use the `step`, `next`, or `cont` command to continue past a breakpoint and execute the rest of the program.

   - `step` executes the next line of the program. If the next line is a procedure call, `step` steps down into the procedure. `step` is described in “Stepping Using the step Command” in Chapter 6.

   - `next` executes the next line; if it is a procedure, `next` executes it but does not step down into it. `next` is described in “Stepping Using the next Command” in Chapter 6.

   - `cont` resumes execution of the program past a breakpoint and does not stop until it reaches the next breakpoint or the end of the program. `cont` is explained in “Continuing Execution after a Breakpoint” in Chapter 6.

Another tool that you can use to follow the execution of your program is the `trace` command (described in “Tracing Program Execution” in Chapter 6). With it you can examine:

- Values of variables at specific points in your program or whenever variables change value.

- Parameters passed to and values returned from functions.

- Line numbers as they are executed.

## Avoiding Common Pitfalls

You may encounter some problems when you debug a program. Common problems and their solutions are listed below.

- If `dbx` does not display variables, recompile the program with the `-g` compiler option. Note that in some cases, this may cause the problem to go away, or its symptoms to change.

- If the debugger's listing seems confused, try separating the lines of source code into logical units. The debugger may get confused if more than one source statement occurs on the same line.

- If the debugger's executable version of the code doesn't match the source, recompile the source code. The code displayed in the debugger is identical to the executable version of the code.

- If code appears to be missing, it may be contained in an include file or a macro. The debugger treats macros as single lines. To debug a macro, expand the macro in the source code.

Prev | Table of Contents | Next
About This Guide |  | Chapter 2. Running dbx