From owner-freebsd-smp Sat Nov 30 15:43:26 1996 Return-Path: owner-smp Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id PAA15582 for smp-outgoing; Sat, 30 Nov 1996 15:43:26 -0800 (PST) Received: from clem.systemsix.com (clem.systemsix.com [198.99.86.131]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id PAA15572 for ; Sat, 30 Nov 1996 15:43:20 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by clem.systemsix.com (8.6.12/8.6.12) with SMTP id QAA09261 for ; Sat, 30 Nov 1996 16:43:17 -0700 Message-Id: <199611302343.QAA09261@clem.systemsix.com> X-Authentication-Warning: clem.systemsix.com: Host localhost didn't use HELO protocol X-Mailer: exmh version 1.6.5 12/11/95 From: Steve Passe To: freebsd-smp@freebsd.org Subject: debugging SMP kernels Mime-Version: 1.0 Content-Type: text/plain Date: Sat, 30 Nov 1996 16:43:17 -0700 Sender: owner-smp@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 to the default 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 #include #include /* 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 =============================================================================== 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 =============================================================================== -------------------------------------- cut ------------------------------------ -- Steve Passe | powered by smp@csn.net | FreeBSD