Debugging a Program With dbx

Chapter 1 Starting dbx

This chapter describes how to start, execute, save, restore, and quit a dbx debugging session.

This chapter contains the following sections:

Basic Concepts

How you start dbx depends on what you are debugging, where you are, what you need dbx to do, how familiar you are with dbx, and whether or not you have set up any dbx environment variables.

Starting a Debugging Session

The simplest way to start a dbx session is to type the dbx command at a shell prompt.

To start dbx from a shell, type:


$ dbx

To start dbx from a shell and load a program to be debugged, type:


$ dbx program_name

dbx Start-up Sequence

Upon invocation, dbx looks for and reads the installation startup file, dbxrc in the directory install-directory/lib, where the default install-directory is /opt.

Next, dbx searches for the startup file .dbxrc in the current directory, then in $HOME. If the file is not found, it searches for the startup file .dbxinit in the current directory, then in $HOME. Generally, the contents of .dbxrc and .dbxinit files are the same with one major exception. In the .dbxinit file, the alias command is defined to be dalias and not the normal default, which is kalias, the alias command for the Korn shell. A different startup file may be given explicitly with the -s command-line option.

A startup file may contain any dbx command, and commonly contains alias, dbxenv, pathmap, and Korn shell function definitions. However, certain commands require that a program has been loaded or a process has been attached to. All startup files are loaded in before the program or process is loaded. The startup file may also source other files using the source or .(period) command. The startup file is also used to set other dbx options.

As dbx loads program information, it prints a series of messages, such as Reading symbolic information...

Once the program is finished loading, dbx is in a ready state, visiting the "main" block of the program (For C, C++, or Fortran 90: main(); for FORTRAN 77: MAIN()). Typically, you want to set a breakpoint and then issue a run command, such as stop in main and run for a C program.


Note -

By default, the loading of debugging information for modules compiled with -xs is delayed in the same way as the debugging information stored in .o files. The dbx environment variable delay_xs lets you turn off the delayed loading of debugging information for modules compiled with -xs and have this information loaded at dbx startup (see "Debugging Without the Presence of .o Files").


If a Core File Exists

If a file named core exists in the directory where you start dbx, it is not read in by default; you must explicitly request the core file. Use the where command to see where the program was executing when it dumped core.

To debug a core file, type:


$ dbx program_name
 core

When you debug a core file, you can also evaluate variables and expressions to see what values they had at the time the program crashed, but you cannot evaluate expressions that make function calls.

Process ID

You can attach a running process to dbx using the process_id (pid) as an argument to the dbx command.


$ dbx your_program_name pid

You can also attach to a process using its process ID number without knowing the name of the program:


$ dbx- pid

Because the program name remains unknown to dbx, you cannot pass arguments to the process in a run type command.

Setting Startup Properties

pathmap

By default, dbx looks in the directory in which the program was compiled for the source files associated with the program being debugged. If the source/object files are not there or the machine you are using doesn't use the same pathname, you must inform dbx of their location.

If you move the source/object files, you can add their new location to the search path. The pathmap command creates a mapping from your current view of the file system to the name in the executable image. The mapping is applied to source paths and object file paths.

Common pathmaps should be added to your .dbxrc file.

To establish a new mapping from directory from to directory to type:


(dbx) pathmap [ -c ] fromto

If -c is used, the mapping is applied to the current working directory as well.

The pathmap command is also useful for dealing with automounted and explicit NFS-mounted file systems with different base paths on differing hosts. Use -c when you try to correct problems due to the automounter because current working directories are inaccurate on automounted file systems.

The mapping of /tmp_mnt to / exists by default.

dbxenv

The dbxenv command can be used to either list or set dbx customization variables. Customize your dbxenv setting by placing them in your .dbxrc file. To list variables, type:


dbxenv

You can also set dbx environment variables. See Chapter 2, Customizing dbx" for more information about setting these variables.

alias

You can create your own dbx commands using the kalias or dalias commands.

Debugging Optimized Code

dbx provides partial debugging support for optimized code. The extent of the support depends largely upon how you compiled the program.

When analyzing optimized code, you can:

However, with optimized code, dbx cannot:

Compiling with the -g Option

To use dbx effectively, a program must have been compiled with the -g or -g0 option. The -g option instructs the compiler to generate debugging information during compilation.

For example, to compile using C++:


% CC -g example_source.cc

To compile optimized code for use with dbx, compile the source code with both the -O (uppercase letter O) and the -g options.

C++ Support and the -g0 Option

In C++, -g turns on debugging and turns off inlining of functions. The -g0 (zero) option turns on debugging and does not affect inlining of functions. You cannot debug inline functions with the -g0 option. The -g0 option can significantly decrease link time and dbx start-up time (depending on the use of inlined functions by the program).

Code Compiled Without the -g Option

While most debugging support requires that a program be compiled with -g, dbx still provides the following level of support for code compiled without -g:

Note, however, that dbx cannot display source code unless the code was compiled with the -g option. This also applies to code that has had strip -x applied to it.

Shared Libraries Need -g for Full dbx Support

For full support, a shared library must also be compiled with the -g option. If you build a program with some shared library modules that were not compiled with -g, you can still debug the program. However, full dbx support is not possible because the information was not generated for those library modules.

Completely Stripped Programs

dbx can debug programs that have been completely stripped. These programs contain some information that can be used to debug your program, but only externally visible functions are available. Runtime Checking cannot work on stripped programs or load objects.

Quitting Debugging

A dbx session runs from the time you start dbx until you quit dbx; you can debug any number of programs in succession during a dbx session.

To quit a dbx session, type quit at the dbx prompt.


(dbx) quit

When you start dbx and attach it to a running process using the process_id option, the process survives and continues when you quit the debugging session. dbx performs an implicit detach before quitting the session.

Stopping Execution

You can stop execution of a process at any time using Ctrl+C without leaving dbx.

Detaching a Process From dbx

If you have attached dbx to a process you can detach the process from dbx without killing it or the dbx session using the detach command.

To detach a process from dbx without killing the process:


(dbx) detach

Killing a Program Without Terminating the Session

The dbx kill command terminates debugging of the current process as well as killing the process. However, kill preserves the dbx session itself leaving dbx ready to debug another program.

Killing a program is a good way of eliminating the remains of a program you were debugging without exiting dbx.

To kill a program executing in dbx:


(dbx) kill

Saving and Restoring a Debugging Run

dbx provides three commands for saving all or part of a debugging run and replaying it later:

save

The save command saves to a file all debugging commands issued from the last run, rerun, or debug command up to the save command. This segment of a debugging session is called a debugging run.

The save command saves more than the list of debugging commands issued. It saves debugging information associated with the state of the program at the start of the run -- breakpoints, display lists, and the like. When you restore a saved run, dbx uses the information in the save-file.

You can save part of a debugging run; that is, the whole run minus a specified number of commands from the last one entered. Example A shows a complete saved run. Example B shows the same run saved, minus the last two steps:

 A.   B. 
   debug     debug
   stop at line     stop at line
    run    run
   next    next
 Saving a Complete Run  next  Saving a Run Minus the Last Two Steps  next
  stop at line   stop at line
  continue   continue
   next    next
   next    next
   step    step
   next     next
    save    save-2

If you are not sure where you want to end the run you are saving, use the history command to see a list of the debugging commands issued since the beginning of the session.

To save all of a debugging run up to the save command:


(dbx) save

To save part of a debugging run


(dbx) save number

where number is the number of commands back from the save command that you do not want saved.

Saving a Series of Debugging Runs as Checkpoints

If you save a debugging run without specifying a filename, dbx writes the information to a special save-file. Each time you save, dbx overwrites this save-file. However, by giving the save command a filename argument, you can save a debugging run to a file that you can restore later, even if you have saved other debugging runs since the one saved to filename.

Saving a series of runs gives you a set of checkpoints, each one starting farther back in the session. You can restore any one of these saved runs, continue, then reset dbx back to the program location and state saved in an earlier run.

To save a debugging run to a file other than the default save-file:


(dbx) save filename

Restoring a Saved Run

After saving a run, you can restore the run using the restore command. dbx uses the information in the save-file. When you restore a run, dbx first resets the internal state to how it was at the start of the run, then reissues each of the debugging commands in the saved run.


Note -

The source command also reissues a set of commands stored in a file, but it does not reset the state of dbx; it merely reissues the list of commands from the current program location.


Prerequisites for An Exact Restoration of a Saved Run

For exact restoration of a saved debugging run, all of the inputs to the run must be exactly the same: arguments to a run-type command, manual inputs, and file inputs.


Note -

If you save a segment and then issue a run, rerun, or debug command before you do a restore, restore uses the arguments to the second, post-save run, rerun, or debug command. If those arguments are different, you may not get an exact restoration.


To restore a saved debugging run:


(dbx) restore

To restore a debugging run saved to a file other than the default save-file:


(dbx) restore filename

Saving and Restoring Using replay

The replay command is a combination command, equivalent to issuing a save -1 followed immediately by a restore. The replay command takes a negative number_of_ commands argument, which it passes to the save portion of the command. By default, the value of -number is -1, so replay works as an undo command, restoring the last run up until but not including the last command issued.

To replay the current debugging run, minus the last debugging command issued:


(dbx) replay

To replay the current debugging run and stop the run before the second to last command, use the dbx replay command where number is the number of commands back from the last debugging command:


(dbx) replay -number

Command Reference

Syntax

$ dbx [-options] [program_name [corefile | process_id]]

Start-up Options

-c cmds

Execute cmds before prompting for input and after loading the program

-C

Preload the runtime checking library  

-d

Used with -s, removes file after reading

-f

Force loading of corefile, even if it doesn't appear to match 

-F

Enable Cfront demangling 

-h

Print the usage help on dbx

-I dir

Add dir to pathmap set

-k

Save and restore keyboard translation state 

-q

Suppress messages about reading stabs 

-r

Run program; if program exits normally, quit dbx

-R

Print the README file on dbx

-s file

Use file instead of .dbxrc or .dbxinit as the startup file

-S

Suppress reading of the installation startup file 

-V 

Print the version of dbx

-w n

Skip n frames on where command

-- 

Marks the end of the option list; use if the program name starts with a dash