DBX Howto Guide


What is dbx

dbx is a tool for source-level debugging and execution of programs.  It
allows you to determine the exact statement that caused a core dump, or
to monitor the exact statements that the program is executing, as opposed
to what you think is happening.  It allows you to examine the contents of
any and all variables and to stop execution at predetermined points.
This can be done without adding additional debugging statements to your
original program, which in some cases make the bugs go away.

Source code may be in C, Fortran, or Pascal.


Preparing Files For dbx

dbx does its work through an enhanced symbol table built into the executable
code.  When compiling programs with cc, gcc, acc, CC, pc, or f77, you must
specify the -g option on the command line so that this enhanced or "good"
symbol table is produced in the object file.  Every step of compilation
(including loading) must include this option.

Examples of compilation and linking are:

		% cc -g program.c foo1.c foo2.c

		% gcc -g program.c foo1.c foo2.c

		% acc -g program.c foo1.c foo2.c

		% CC -g program.c foo1.c foo2.c

		% pc -g program.p

		% f77 -g program.f

After successful compilation, the executable version (better known
as the 'a.out' file) is produced.  This file should be located in
the same directory as your source program(s).

Invoking dbx

To invoke dbx, type 'dbx' followed by the executable file name.  For example,
if the executable file name is 'a.out', you will type:

		% dbx a.out

This will be followed by the following message (this may vary depending on
version of dbx):
	
		dbx version 3.17 ...
		Type 'help' for help
		reading symbolic information ...
		(dbx)

The '(dbx)' prompt is the debugger's command line prompt.

Exiting dbx

To exit the dbx shell, type 'quit' at the dbx prompt:

		(dbx) quit

Advantages/Disadvantages of Using dbx with Core File

Typically when you execute a program that unexpectively terminate
during runtime (ie, your program "crashed"), a 'core' file is
produced containing symbolic information about the program at the
point it stopped executing.

When dbx is invoked with a 'core' file in the current working directory,
it will extract information about the program at the point it failed
(i.e., core dumped).  The 'where', 'up' and 'down' commands are well
suited to obtain this type of information.  However, this will limit
the scope of debugging to the procedure that the program terminated.
To extend scope beyond the current procedure, you must either
remove the core file from the current directory before invoking dbx
or explicitly specify the procedure you want to make visible.  For
example,
	(dbx) print `test`main`i
will display the current value of variable 'i' in procedure 'main',
in source file 'test'.

The dbx command examples given in this help article assume no core
file exists (unless explicitly specified) in the current working
directory.

Debugging Techniques

Using dbx's Help

To list a summary of dbx commands available, type 'help' at (dbx)
prompt:
		(dbx) help

You can obtain additional information on a specific command by typing
'help <cmdname>'.  For example,

		(dbx) help trace

will display the command syntax and a brief description of the
trace command.

Summary of dbx Commands

      ================================
          Execution and Tracing
      ================================
run       execute object file
cont      continue execution from where it stopped
trace     display tracing information at specified place
stop      stop execution at specified place
status    display active trace and stop requests
delete    delete specific trace or stop requests
catch     start trapping specified signals
ignore    stop trapping specified signals
step      execute the next source line, stepping into functions
next      execute the next source line, even if it's a function

      =======================
          Displaying Data
      =======================
print     print the value of an expression
whatis    print the declaration of a given identifier or type
which     print outer block associated with identifier
whereis   print all symbols matching identifier
assign    set the value of a variable

      ======================================
          Function and Procedure Handling
      ======================================
where     display active procedures and functions on stack
down      move down the stack towards stopping point
up        move up the stack towards main
call      call the named function or procedure
dump      display names and values of all local variables

      ==============================================
          Accessing Source Files and Directories
      ==============================================
edit      invoke an editor on current source file
file      change current source file
func      change the current function or procedure
list      display lines of source code
use       set directory list to search for source files
/.../     search down in file to match regular expression
?...?     search up in file to match regular expression

      ================================
          Miscellaneous Commands
      ================================
sh        pass command line to the shell
alias     change dbx command name
help      explain commands
source    read commands from external file
quit      exit the debugger

Listing Source Code

If you invoked dbx on an object file, you can list portions of your
program and associated line numbers in the program's source file.
For example, to list lines 1 through 12 of object file, type:

	(dbx) list 1,12
	      1 #include <stdio.h>
	      2
	      3 main()
	      4 {
	      5      printf("goodbye world!\n");
	      6      dumpcore();
	      7 }
	      8
	      9 dumpcore()
	     10 {
            11	     abort();
	     12 }

If the range of lines start past the end of file, dbx will tell
you the program has only so many lines.

You can also list the first few lines of a procedure by typing its
name.  For example, to list the first 10 lines of procedure 'main',
type:
	(dbx) list main
	      1 #include <stdio.h>
	      2
	      3 main()
	      4 {
	      5      printf("goodbye world!\n");
	      6      dumpcore();
	      7 }


Locating Where a Program Failed or Core Dumped

If your programs fails to execute properly, you probably want to find
out the procedures that were active when the program crashed.  Use
the 'where' command to list this location:

Example:

	(dbx) where
	dumpcore() line 22 in "program.c"
	main(), line 9 in "program.c"
	(dbx)

This indicates that program crashed on line 22, file 'program.c',
function 'dumpcore'.  The second line indicates that 'dumpcore' was
called from function 'main' on line 9.

Note: in order for this command to work as expected, there must be
a 'core' file located in your current working directory.  This core
file contains symbolic information about the program and is
produced automatically when a core dump occurs as the program is
executed.

Displaying Data

Displaying Variables Using 'print'

	syntax: print expression [,expression ...]

This command will display the current value of variable(s)
expression.  For example,
	
	(dbx) print lim, i

will display the current value of variables 'lim' and 'i'.
If a core file exists, and 'print' is immediately invoked upon entering dbx,
it will display the values of the variables specified at the point
it core dumped.

Displaying Variables After a Breakpoint Using 'display'

	syntax: display [expression [,expression ...]]

This command will display the values of expression(s) each time
execution of the debugged program stops.  Refer to Setting
Breakpoints of this help article for stopping execution.
For example,

	(dbx) display lim, i

will display the values of variables 'lim' and 'i' every time a
breakpoint is detected.

Also,
	(dbx) display

will list all variables currently set by the 'display' command.


To remove an expression from the display list, use the 'undisplay'
command.

	(dbx) undisplay lim

will stop displaying the variable 'lim' while all others still
active will be displayed.

Displaying the Type of an Identifier

To display the type of a given identifier, use the 'whatis'
command.

For example,

	(dbx) whatis lim

will display the type of variable 'lim'.  For example, if 'lim' was
declared to be of type integer (in C), whatis will display its
type followed by its identifier, i.e.. int lim; .

whatis can also display members of structure, union or enumerated
type.  For example, if the following was declared in a C program:
	
		typedef struct students {
			int idnumber;
			float gpa;
			int rank;
		} students;


	(dbx) whatis students

will display the typedef structure above.
	

Displaying All Occurrences of an Identifier

To display all symbols whose name matches a given identifier, use
the 'whereis' command.  For example,

	(dbx) whereis lim

will display the full path of all occurrences of variable 'lim'.

Displaying All Variables in a Procedure or Function

The 'dump' command will display the names and values of all local
variables and parameters in the currently active procedure or
function.  If dbx is invoked with a 'core' file in the current
working directory, dump will display information of the procedure
where the core dump occurred.

Changing Value to Expressions

The 'assign' or 'set' command can be used to assign a value to a
variable.

For example,

	(dbx) assign i = 0

		-or-

	(dbx) set i = 0

will set the current value of i to 0 (zero).

Setting Breakpoints

Breakpoints allows you to explicitly specify where to suspend execution
of the program.  This is especially beneficial when attempting to
display variables local in procedures or functions which may not be visible
otherwise.

Note: various breakpoint commands provide an optional 'if condition' as
part of its command syntax.  If this is specified, you must use the
correct conditional syntax as the language used.  For example, to specify
"x greater than 10", in C it will be x>10, but in Fortran it will be
x.GT.10.  The examples provided in this help article uses C syntax.

Stopping Execution at a Given Line Number

	syntax: stop at line_number [if condition]

Execution may be suspended at a line number or at a line
number based on a specified condition.

Examples:

	(dbx) stop at 15

		-or-

	(dbx) stop at 15 if x>10

Stopping Execution at a Procedure/Function

	syntax: stop in procedure/function [if condition]

Stop execution at the first line of the given procedure or function
name.

Examples:

	(dbx) stop in foo

		-or-

	(dbx) stop in foo if x>10

Stopping Execution Whenever a Value/Condition Changes

	syntax: stop variable [if condition]

	syntax: stop if condition

If condition is not specified, dbx will stop every time the value of
variable changes.

Examples:

	(dbx) stop foo

		-or-

	(dbx) stop foo if x>0

		-or-

	(dbx) stop if x>0

Displaying Currently Active Breakpoints

	syntax: status [>filename]

Status will display all 'trace', 'stop' and 'when' commands set
using dbx.  A command number is listed for each command.  The
filename argument (>filename) causes the output of status to be
sent to the specified filename.

Removing All or a Specified Breakpoint

	syntax: delete all

	syntax: delete command-number [, command-number ...]

Removes ALL or specified 'trace', 'when' and/or 'stop' commands
corresponding to the given command-number(s).  The 'status' command
displays numbers associated with these commands.


Running and Tracing Programs

Executing the Code

	syntax: run [args] [<filename] [>filename] [>>filename]

You can execute and trace through your code using the 'run' command.
Run will start executing the object file specified on the dbx
command line (i.e., % dbx a.out), passing 'args' as command-line
arguments; <, >, and >> can be used to redirect input and output in
the usual manner.

Examples:

	(dbx) run
Will execute program from beginning expecting no arguments.

	(dbx) run foo1 foo2
Will execute program that requires 2 arguments as inputs.

	(dbx) run < inputfile
Will execute program that takes input from a disk file.

	(dbx) run > outfile
Will execute program and redirect all output to a disk file.

	(dbx) run >> outfile
Will execute program and append all output to a disk file.

Resuming Execution After a Breakpoint

	syntax: cont [at source-line-number]

This command will continue execution from where it stopped, or, if
the clause 'at source-line-number' is given, at that line number.

	(dbx) cont
Will resume execution from the current breakpoint until the next
breakpoint is encountered or the program finishes (whichever is
occurs first).

	(dbx) cont 15
Will resume execution on line 15, relative to the current file and must
be within the current procedure/function.

Executing Certain Number of Lines Before Stopping

	syntax: step [n]

This command will execute through the next n source lines and then stop.
If 'n' is not specified, it is taken to be one (single stepping).
Procedure and function calls that are executed are also counted,
i.e.. 'step' steps into them.

Also,
	syntax: next [n]

will perform the same function as the 'step' command except procedure
and function calls are counted as one statement, i.e.. 'next' steps over
them.

Display Trace Information During the Execution of a Program

Trace Through Every Statement

	syntax: trace

   will display every source line before it is executed.  This can be
   used to monitor each execution step of your program.  For example,
   to trace through your program starting at line 15, you can
   perform:

	(dbx) stop at 15
	(dbx) trace
	(dbx) run
	(dbx) cont

Trace Through a Particular Line

	syntax: trace source-line-number [if condition]

   will display information about the source-line-number specified
   each time it is encountered.  The 'if condition' can be used to
   display information only when the condition is true.  For example,
   to display trace information for each occurrence of line 15, you
   will perform:
	(dbx) trace 15

   Or to display it if variable 'i' is greater than 5:
	(dbx) trace 15 if i>5

Trace Through a Procedure or Function

	syntax: trace procedure/function [if condition]

   will restrict tracing information to be displayed only while
   executing inside the given procedure or function.  Note that the
   procedure/function traced must be visible in the scope in which
   the trace command is issued.  Every time the procedure or
   function is called, it will display information telling what
   routine called it, from what source line it was called, and what
   parameters were passed to it.  In addition, its return is noted,
   and if it is a function, the return value is also displayed.
 

Tracing a Variable

	syntax: trace variable [in procedure/function] [if condition]

   will display information about the variable specified when the
   value changes.

   Examples:
	
	(dbx) trace i

   will show trace information of variable 'i' in the current
   active procedure.  If dbx is run with no 'core' file in the
   current working directory, it will trace the variable from
   the main procedure.  If there is a 'core' file, dbx will
   trace the variable in the procedure where your program
   terminated (or core dumped).


	(dbx) trace i in ProcName

   will explicitly specify tracing variable 'i' in procedure (or
   function) named 'ProcName'.  Information on this variable
   will only be displayed if the value of 'i' changes.


	(dbx) trace i in ProcName if i>5

   will perform the same operation as above except only if the
   specified condition ( i>5 ) is true.


Executing a Procedure and Function

	syntax: call procedure-name(parameters)

This command will execute the named procedure (or function), with the
parameters specified.  If any breakpoints are encountered, execution
halts and the dbx command level is reentered.
Note: the number of parameters and type must match those specified in
the source code.

Example:

	(dbx) call MyProc(foo1, foo2)

will execute procedure 'MyProc' passing 'foo1' and 'foo2' as arguments.