[net.unix] Help using dbx

mbr@aoa.UUCP (Mark Rosenthal) (04/23/86)

I posted the following article some weeks ago.  I fear it may have dropped
into the bit-bucket, so I am reposting it.

It appears that most vendors have given up on 'sdb' in favor of 'dbx' or
some derivative of 'dbx'.  I find that although 'dbx' is generally more
powerful than 'sdb' it lacks some capabilities that I used to depend on quite
heavily.  If anyone is familiar with how to do the following with 'dbx',
please let me know.  You will earn my undying gratitude.

Note that I have not used sdb in over a year.  The examples I give below are
from my own faulty memory and may not be 100% accurate.

By the way, I am running 'dbx' on a Sun workstation.

1.  I'd like to be able to specify the format in which a variable is to be
    displayed.  If I have a variable (char *cp), I could do the following
    with 'sdb':

	me:	cp/x		or:	cp/s		or:	cp/
	sdb:	0x7fff3ec		string			string

    With 'dbx', the dialogue is something like:

	me:	print cp
	dbx:	0x7fff3ec
	me:	0x7fff3ec/s
	dbx:	string

    Having to type back into dbx what it just typed at me is a pain.

2.  The man page for 'dbx' claims that the command to display a memory location
    is:

	[address] / [count] [mode]

    where everything but the "/" is optional, and that "if no address is
    specified, the address following the one displayed most recently is used".
    Unfortunately, there is also a "/" command which searches the source file
    for a string.  Typing "/" reports:

	"No saved search string"

    rather than showing me the next location.  This makes it quite a chore to
    examine an array.  Arrays of structures are even worse.

3.  With 'sdb', I could display lines of code relative to the current line.
    'dbx' appears to limit me to specifying absolute line numbers.  This means
    that anytime I hit a breakpoint and want to see some context, I have to
    read the current line number from the screen, do some quick arithmetic,
    and type "list from_line,to_line".  The concentration required to do that
    is a distraction from the problem I am trying to solve, namely finding and
    fixing bugs in a program.  A symbolic way of referencing dbx's line counter
    would solve the problem, but I can find no mention of any such capability
    in the documentation.  I'd like to be able to do something like:

	alias w list .-5,.+5

    and then just type "w" to see context around the current line.

4.  A common construct in C is a linked list of structures.

	struct foo
	{
		struct foo *next;
		int	data;
		char	*moredata;
		/* Etc., etc., etc. */
	};

	struct foo *foobar;

    Let's say my code malloc()s instances of foo, and links them in to the list
    beginning at foobar.  I am at a breakpoint, and I want to examine the list.

    I don't remember the exact sequence I used with sdb, but it went something
    like:

	me:	foobar/		show the value of foobar
	sdb?:	0x7ff2ea
	me:	.->/		show what the last displayed value points at
				    (i.e. foobar->next)
	sdb?:	0x7e3720
	me:	+/d		show the next location in decimal
				    (i.e. foobar->data)
	sdb?:	3
	me:	+/s		show the next location as a string pointer
				    (i.e. foobar->moredata)
	sdb?:	string data
	me:	-		back up one location (to foobar->data)
	sdb?:	3
	me:	-		back up one location (to foobar->next)
	sdb?:	0x7e3720
	me:	.->/		show what the last displayed value points at
				    (i.e. foobar->next->next)
	sdb?:	0x748238
	me:	+/d		show the next location in decimal
				    (i.e. foobar->next->data)
	sdb?:	2
	me:	+/s		show the next location as a string pointer
				    (i.e. foobar->next->moredata)
	sdb?:	more chars
	me:	-		back up one location (to foobar->next->data)
	sdb?:	2
	me:	-		back up one location (to foobar->next->next)
	sdb?:	0x748238
	me:	.->/		show what the last displayed value points at
				    (i.e. foobar->next->next->next)
	sdb?:	0		end of list
	me:	+/d		show the next location in decimal
				    (i.e. foobar->next->next->data)
	sdb?:	1
	me:	+/s		show the next location as a string pointer
				    (i.e. foobar->next->next->moredata)
	sdb?:	still more chars

    To do the same thing with dbx, the best I've been able to come up with
    so far is:

	me:	print foobar
	dbx:	0x7ff2ea
	me:	print foobar->data
	dbx:	3
	me:	print foobar->moredata
	dbx:	string data
	me:	print foobar->next
	dbx:	0x7e3720
	me:	print foobar->next->data
	dbx:	2
	me:	print foobar->next->moredata
	dbx:	more chars
	me:	print foobar->next->next
	dbx:	0x748238
	me:	print foobar->next->next->data
	dbx:	1
	me:	print foobar->next->next->moredata
	dbx:	still more chars
	me:	print foobar->next->next->next
	dbx:	0		end of list

    Note that the sequence of commands I type to sdb is relatively simple,
    and stays the same no matter how far through the list I've gone:

	me:	foobar/
	me:	.->/
	me:	+/d
	me:	+/s
	me:	-
	me:	-
	me:	.->/
	me:	+/d
	me:	+/s
	me:	-
	me:	-
	me:	.->/
	me:	+/d
	me:	+/s

    whereas with dbx, I have to retype the entire sequence from the starting
    point every time:

	me:	print foobar
	me:	print foobar->data
	me:	print foobar->moredata
	me:	print foobar->next
	me:	print foobar->next->data
	me:	print foobar->next->moredata
	me:	print foobar->next->next
	me:	print foobar->next->next->data
	me:	print foobar->next->next->moredata
	me:	print foobar->next->next->next

    This makes a list of length 4 a pain to deal with, and a list of length 16
    prohibitive.  Linked lists with hundreds of elements are not uncommon.
    Do the authors of 'dbx' really intend that I should have to type:

print foobar->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->next->next->next->next->next->next->next->next->next->next->next->next->
next->data

    to get to the 128'th (or did I only type next 127 times?) item in a list?
    There MUST be a better way.  Can somebody PLEASE enlighten me.

Sorry.  I got a bit carried away there.  I'll be alright in a second.

-- 

	Mark of the Valley of Roses
	...!{decvax,linus,ima,ihnp4}!bbncca!aoa!mbr
	...!{wjh12,mit-vax}!biomed!aoa!mbr

guy@sun.UUCP (04/25/86)

> By the way, I am running 'dbx' on a Sun workstation.

Which is different from the 4.2BSD "dbx", which is in turn different from
the 4.3BSD "dbx", so note that this discussion applies only to the Sun
version.

> 1.  I'd like to be able to specify the format in which a variable is to be
>     displayed.

To print the variable "foo" in a particular format, &foo/<format> should
suffice.

> If I have a variable (char *cp), I could do the following with 'sdb': ...

In this case, you don't want to display "cp", you want to display what "cp"
points to.  The Sun UNIX 3.2 version (probably the 3.0 version as well) will
print what a "char *" points to, as a string, as well as its value.  If you
say "print *cp", it will print the char that "cp" points to.

> 2.  The man page for 'dbx' claims that the command to display a memory
> location is: ...
> ... rather than showing me the next location.  This makes it quite a chore
> to examine an array.  Arrays of structures are even worse.

The fact that the man page says anything indicates you definitely don't have
3.0.  I don't know what 3.0 added.

First, why are you using the display command to examine an array?  "print
array[N]" seems sufficient to examine the Nth element.  If the entire array
is small enough that printing it in its entirety is reasonable, try "print
array".

Second, if you've just displayed a location using "/", you don't want to use
something like a naked "/" to display the same location again.  You want to
display the next location, which can be done (at least in 3.0 and later
releases) using "+/".

> 3.  With 'sdb', I could display lines of code relative to the current line.
>     'dbx' appears to limit me to specifying absolute line numbers.  This
>     means that anytime I hit a breakpoint and want to see some context, I
>     have to ...

"l" by itself will, after hitting a breakpoint, print the line the
breakpoint occurred on and the next 10 lines.  Repeating the "l" will step
through the file.  Unfortunately, this doesn't give you a window *around*
the breakpoint.  If you have "dbxtool", and are doing your debugging on a
workstation, you can use that.

> 4.  A common construct in C is a linked list of structures. ...
> (discussion of stepping through the list)

What's needed here is a notion of variables inside "dbx", so that you can
have an alias which prints whatever <variable> points to and sets <variable>
to <variable>->next.  This is a more general solution than what "sdb"
offers; I can imagine data structures which "sdb" would not be able to scan
through conveniently.

Unfortunately, "dbx" doesn't have this notion.  The 4.3BSD one might.
Perhaps "dbx" should have more such programming-language characteristics, so
that it could be "programmed" to display more complicated data structures.

I also note from this an other examples that you seem to be using "sdb" and
"dbx" as a symbolic debugger which knows about source lines, but not one
which knows about data structures.  "dbx" can be used that way, but it
wasn't really intended to be so used.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.arpa

przemek@gondor.UUCP (Przemyslaw Klosowski) (04/28/86)

====================================================================
 
 The only information I could get about dbx is the manual page. Is there
in the big world something more informative? In particular I didn't succeed
in calling the procedure with the parameter which has non-predeclared type.
The man page says something like ' typename(param)', but 'struct kuku(...)'
is rejected with complaint about undeclared type 'struct' -- we apparently 
have totally different things in mind.
 Apologies if I screw up something with net.distribution -- this is my very
first posting.
				przemek
				przemek@gondor.UUCP
				przemek@psuvaxg.bitnet
PS Of course I use dbx for C programs.

jerryp@tektools.UUCP (Jerry Peek) (04/30/86)

There was a dbx tutorial in the January 1986 issue of UNIX Review magazine,
pp. 78-85.