Debugging with the trace Command


The dbx debugger lets you approach debugging from different 
angles.  This time you will debug the program with the trace 
command.


The method used in debugging with trace is different from that 
used when debugging with breakpoints.  Although you can set breakpoints and 
use trace at the same time, trace works best when 
you let large pieces of the program run without halting.  With 
trace you tell the debugger to monitor specific variables and 
functions as the program runs, then you let the program execute the lines of 
code you want traced.  The trace method of debugging can be more 
efficient than the breakpoint method, but unfortunately dbx 
sometimes dies when you try to use the trace command.


In the case of blankstrip, you are interested in discovering 
what happens to the character string entered at the the terminal.  That string 
is held in main.c's instring variable.  Start up the debugger, tell 
dbx to trace the instring 
variable, then run the program:


Coke-21: dbx a.out

dbx version 3.12 of 12/6/85 8:35 (paris).

Type 'help' for help.

reading symbolic information ...

(dbx) trace instring

[1] trace instring in main.main

(dbx) run

Segmentation fault (core dumped)

coke-22:%}


What happened?  The debugger itself just crashed on us, and produced a core 
file.  Unfortunately, dbx can't trace array 
variables in main() procedures without dying.  You can 
however, use trace to monitor array variables in subfunctions. 
 In the case of our program, you will be able to trace the s 
variable in tblank.c.


Before you restart the debugger, you should remove the core file that 
dbx produced when it crashed:


coke-23: rm core


If you don't remove core, dbx will load the file when you 
restart the debugger. Since the core file has little to do with your program 
(it is an image of a dbx crash), it is meaningless to the task 
at hand.


Start dbx again, tell the debugger to trace the 
string array in blank, then run the program:


coke-24: dbx a.out

dbx version 3.12 of 12/6/85 8:35 (paris).

Type 'help' for help.

reading symbolic information ...

(dbx) trace s in tblank

[using tblank.tblank.s]

[1] trace tblank.tblank.s in tblank.tblank

(dbx) run

Enter a string with leading and trailing blanks:

    asdf

input = '    asdf    '

initially (at line 7 in "tblank.c"):    tblank.tblank.s

= "asdf    "

output = 'asdf    '


execution completed}


In this instance, trace tells you that 
s--actually tblank.tblank.s--is initially 
set to "asdf ".  It doesn't give you any more information 
because the string does not get modified. Try running the program again, and 
this time trace the slength variable as well:


(dbx) trace slength in tblank

[2] trace slength in tblank.tblank

(dbx) run

Enter a string with leading and trailing blanks:

    asdf

input = '    asdf    '

initially (at line 7 in "tblank.c"):    tblank.tblank.s

= "asdf    "

initially (at line 7 in "tblank.c"):    slength = 4

after line 9 in "tblank.c":     slength = 8

after line 14 in "tblank.c":    slength = 9

output = 'asdf    '


execution completed

(dbx) quit


This time trace displays some important information.  It shows 
that slength never becomes smaller, indicating that 
tblank skips the while loop.  Knowing this 
information, you can now set a breakpoint in tblank() and use 
print to display the elements of the s array as you did in 
the previous debugging session.