snapshot with kgdb support




WHee...  Ok, this snapshot/patch set will get you full kgdb debugging
support at the very least on sun4c boxes.  First the files:

vger.rutgers.edu:/pub/linux/Sparc/snapshots/sparclinux-950827.tar.gz
vger.rutgers.edu:/pub/linux/Sparc/patches/sparc-1.3.20-1-950827.tar.gz

And for convenience I have placed a static gdb-4.14 Sunos4.13 binary

vger.rutgers.edu:/pub/linux/Sparc/kgdb/gdb4.14-sunos413.gz

Whee!  Ok seriously, there are two things you need to do in order to
have a usable kgdb debugging setup.  You need two machines, one for
booting the kernel image (a sun4c of some sort) and another machine to
which you can hook up a serial port to the boot-test box and for which
you have a gdb which understands the a.out Sparc/SunOS executable
format.

Ok, next you'll have to dork with arch/sparc/Makefile and switch the
two CFLAG lines, one is commented out and it is the one with the
-ggdb3 flag to have gcc produce the proper debugging symbols in the
vmlinux kernel image.  So just swap the two.

Ok, now build the sucker, warning it is going to be huge!  Most of my
images are around 6MB or more.  Once you have the vmlinux image at the
top level of the build directory, keep this one unstripped and full of
the debugging symbols, the gdb process will need it.  You can copy the
image onto the boot-machine's kernel image area and strip it there to
save space.  Ok, now cd into the top level directory of the kernel
sources where the humungo ./vmlinux is, on the machine where you can
run the gdb process.

Fire up gdb with

gdb ./vmlinux

May take some time as the symbols are being read in (those proficient
with using gdb under emacs might want to do that as it is very nice
and allows direct editing of the sources as you trace through things
and is what I do myself).  Ok, now you should have the (gdb) prompt
ready.

On the boot-test box make sure the kernel image is ready (stripped or
unstripped, doesn't really matter as the Sun boot-loader doesn't load
any of the symbol table into memory when linux is booted).  Now use
the magic kgdb arguments to tell Linux what is going on.  For example
I use:

Type 'help' for more information
ok boot le()vmlinux kgdb=ttya

This tells the kernel that you will be running a kgdb session on what
would be /dev/ttya under SunOS and that is the channel that kgdb
debugging packets will go across.  Now linux will come up and tell you
"entering kgdb session..." or something similar.

At this point go back to your (gdb) prompt and go:

(gdb) target remote /dev/ttya

Replacing '/dev/ttya' to which ever serial line device is connected to
the linux box.  Gdb will now put the serial line into raw mode and try
to get an ack for a packet whose command is basically a nop to see if
the kgdb-stub is functioning properly (all kgdb packets have a
checksum and thus it is not just waiting for an ack character).  Once
this succeeds you'll see the source point at which the kernel is
stopped etc.  It's just like debugging a real process.

NOTES AND WARNINGS:

1)  Don't try to trace into prom address space, you will lose.  I have
    put safety guards in the code, and gdb just will fail to set the
    breakpoint.  I am working on a way to allow tracing into the PROM
    boot monitor though... more on this later...

2)  I have tried as hard as possible to make things work as quickly as
    possible, but on 20Mhz sun4c Sparcs with the broken zilog chugging
    at 9600 baud, there is definately a performance penalty.  It is
    reasonable, however you might as well go get lunch when you set
    watchpoints to tell gdb to break when a variable gets changed as
    it must stop at every instruction and look around, this means lots
    of bandwidth over the serial port ;-(

Once in a while the stub in the kernel and the user-level gdb process
will get confused and get un-synched, either because a packet is
having characters dropped, or because linux has become foo-bar
completely.  Usually if you hit Control-C a couple times to gdb it
will ignore the error'd packets and just tell the stub to stop and
tell gdb where it is at so you can change your command around a bit.

One final note, to make things work more quickly, if you want to use
the until feature to pass over a loop completely, *dont*, it takes
forever and has the same problem the watchpoint feature has which is
tons of serial port bandwidth.  Place a breakpoint after the last
source line of the loop instead, much faster.  Also, the 'finish'
command is very handy and is quick.

This is what I consider mostly functional besides the problem with
stepping into the boot monitor PROM address space.  Backtraces work,
full typing and structure output niceties etc.  For instance, a nice
thing to see is

(gdb) set print pretty on
(gdb) p/x *current

or

(gdb) p/x (struct sparc_stackf) *current->ksp

or take the address of some process other than current, place it's
task struct ptr in a convenience variable and go:

(gdb) p/x (struct switch_stack) *$proc

Assuming you've placed the task struct ptr in $proc beforehand.  Have
fun, you can play with this for hours and watch things go. ;)

Later,
David S. Miller
davem@caip.rutgers.edu