Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Nov 1996 16:43:17 -0700
From:      Steve Passe <smp@csn.net>
To:        freebsd-smp@freebsd.org
Subject:   debugging SMP kernels
Message-ID:  <199611302343.QAA09261@clem.systemsix.com>

next in thread | raw e-mail | index | archive | help
Hi,

here is a VERY ROUGH 1st draft of how to go about setting up a remote serial
debug session for the SMP kernel.  Send comments etc.  I know its full of
holes, but it should get you started.

-------------------------------------- cut ------------------------------------
===============================================================================
To debug via a 'serial terminal' and ddb:

 Terms used in this discussion:

  HOST:  the machine with which you are providing "terminal facilities".
         Note that this could be a RS-232 terminal, but using an XTerm
         on a computer gives many advantages such as output capture, etc.

  TARGET:  The machine that the SMP kernel is being run on.

  PORT:  the serial port used on the machine.  This must be /dev/cuaa0
         on the TARGET (ie SMP kernel) machine, but can be any available
         port on the HOST machine.

  For my examples below I will use:
         HOST == larry, larry's PORT == /dev/cuaa1
         TARGET == moe,  moe's PORT == /dev/cuaa0 (COMCONSOLE *must* be cuaa0)

1) setup a null-modem connection between PORT on the HOST machine and
   PORT on the TARGET machine.

2) create an entry in HOST:/etc/remote that looks like:

	moe:dv=/dev/cuaa1:br#9600:pa=none:el=^J^M:

    'moe' is the target machine name.
    'dv=/dev/cuaa0' sets the port to /dev/cuaa0
    'br#9600' sets the baudrate to 9600
    'pa=none' disables parity generation/checking
    'el=^J^M' adds <linefeed> to the default <return> as legal EOL chars.
              optional, this makes output from inside an emacs SHELL cleaner.

    see "man 5 remote" for further details.

   to get the proper permissions for this to all work on my 2.1.5
   box I set things like this:

   ls -l HOST:/PORT
   crw-rw----  1 uucp  dialer   28, 129 Nov 30 14:48 /dev/cuaa1
                       ^^^^^^
   HOST:/etc/group
   [ add yourself to group 'dialer' ]
                            ^^^^^^
3) add the following to your SMP kernel config file:

options		DDB			# enable the kernel debugger.
options		COMCONSOLE		# prefer serial console to video
options		BREAK_TO_DEBUGGER	# a BREAK on a comconsole goes to DDB

   then the usual config/make depend/make/make install.

4) run "tip moe" on the HOST machine.

5) reboot the TARGET machine.  It should show output as usual on the system
   console up thru the point of loading the kernel.  If you use options
   to boot or a kernel other than 'kernel' you will need to type to the TARGET
   console.

6) the ONLY way I could get BREAKS sent by tip to be seen by the TARGET
   machine was to "cat >/dev/cuaa0 &" as root on the TARGET machine after
   it comes up.  Something to do with the port needing to be open to catch
   the INTerrupts generated by the BREAK.

7) you will see all the normal startup messages appear on the HOST screen.
   To trap to the debugger hit a BREAK character.  To send a BREAK from
   tip use "~#".  Note the the "~" must be the 1st char on the line to
   be recognized by tip.

8) running tip from an emacs shell:

    for some reason emacs echos something that causes ddb to exit the
    debug trap as soon as it enters it.  To get around this I built the
    following bandaid:

--------------------------------- cut ------------------------------
/*
 * genbrk.c
 */

#include <stdio.h>
#include <sgtty.h>
#include <fcntl.h>

/* the port that tip uses to talk to the TARGET COMCONSOLE */
#error fix the following line and remove this one to compile
#define DEVICE  "/dev/cuaa?"

main( int argc, char* argv[] )
{
    int fd;

    fd = open( DEVICE, O_WRONLY );
    ioctl( fd, TIOCSBRK, NULL );
    sleep(1);
    ioctl( fd, TIOCCBRK, NULL );
}
--------------------------------- cut ------------------------------

    you can execute it with the emacs command META-!  Lock it down for
    security with:

    chown root:dialer /usr/local/bin/genbrk
    chmod 4750 /usr/local/bin/genbrk

   If anyone nows how to tickle emacs so this is unnecessary please
   let us know.

---
 Steve Passe <smp@csn.net>

===============================================================================
To debug via remote gdb:

---
Eric L. Hernes provided the following, which he derived from a message
Julian sent to -hackers a while back.

---
In a nutshell here:

1) null-modem sio0 on the `to be debugged' machine to a tty
   on another machine.  I'm using sio0 <-> sio0 on jake and tess.  `jake'
   is my main desktop, which is the smp box.  tess is my normal kernel-hacking
   machine.  Their role's are reversed for this project.

2) I set up the kernel sources on the `stable' machine.  For smp work
   this is tess.  For normal kernel work, this is jake.  So I've got
   my smp kernel source on tess.  config your kernel with `config -g'
   to put debugging symbols in the kernel.

3) make depend all, as normal.  copy kernel to kernel.debug or something
   it'll be around 9 Meg! then `strip -d' the kernel to get rid of debugging
   symbols, but leave the symbol table intact (so things like ps will work)
   Julian suggested patching the Makefile with something like:

(warning: cut-n-paste tab breakage)
--- Makefile~        Mon Nov  4 20:19:14 1996
+++ Makefile    Tue Nov  5 11:16:44 1996
@@ -71,6 +72,8 @@
 .endif
 SYSTEM_LD_TAIL= @echo rearranging symbols; \
        symorder -m ${SYMORDER_EXCLUDE} symbols.sort $@; \
+       cp $@ $@.debug; \
+       strip -d $@; \
        size $@; chmod 755 $@
 
 BEFORE_DEPEND=linux_assym.h 

   This is the kernel that will be booted.

4) install `kernel' (the strip -d'ed) one on the target machine.

5) start gdb in the kernel compile directory on the stable machine.
   The three magical commands you need to run within gdb are: 
   A) `set remotebaud 9600'
        (or whatever baudrate, this works for me, I've heard some
        complaints about speed);
   B) `file kernel.debug'
        (or whatever file still has debugging symbols in from step 3)
   C) target remote /dev/cuaa0
        (or whatever the tty device is)

6) reboot.  At the boot prompt, you can type -g to get traps to go
   to remote gdb.  My boot blocks are too old to support this, and
   I'm lazy so I run -d at the boot prompt and type `gdb' at the
   ddb prompt.  This reports something like `next trab will go to remote
   gdb'. then you can set breakpoints, and continue etc...

7) the next trap on the debug'ed machine will give a standard gdb prompt
   with the source line number printed!  most gdb commands work as expected.

8) There are some flakey things, like I've not been able to reboot the
   remote machine from within gdb, I always go for the reset switch.
   Sometimes gdb reports that the program seg-faulted, then you may as
   well head for the reset too.

9) you can substitute in your favorite front end for gdb in step 5.
   I've used xemacs, ddd, tkgdb, gdb, xxgdb, (any more?)

---
 Eric L. Hernes <erich@lodgenet.com>

===============================================================================
-------------------------------------- cut ------------------------------------
--
Steve Passe	| powered by
smp@csn.net	|            FreeBSD




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611302343.QAA09261>