.\" Copyright (c) 1983 The Regents of the University of California. .\" All rights reserved. .\" .\" %sccs.include.redist.roff% .\" .\" @(#)kdebug.ms 6.6 (Berkeley) 04/17/91 .\" .bd S B 3 .de UX .ie \\n(GA>0 \\$2UNIX\\$1 .el \{\ .if n \\$2UNIX\\$1* .if t \\$2UNIX\\$1\\f1\(dg\\fP .FS .if n *UNIX .if t \(dgUNIX .ie \\$3=1 is a Footnote of Bell Laboratories. .el is a Trademark of Bell Laboratories. .FE .nr GA 1\} .. .de cw .nr >G \\n(.f \" save current font .ft CW .. .de pw .ft \\n(>G .. .TL Using ADB to Debug the .UX Kernel .AU Samuel J. Leffler and William N. Joy .AI Computer Systems Research Group Department of Electrical Engineering and Computer Science University of California, Berkeley Berkeley, California 94720 .de IR \fI\\$1\fP\\$2 .. .de DT .TA 8 16 24 32 40 48 56 64 72 80 .. .AB .PP .FS *DEC and VAX are trademarks of Digital Equipment Corporation. .FE This document describes the facilities found in the 4.3BSD version of the VAX* .UX debugger .I adb which may be used to debug the .UX kernel. It discusses how standard .I adb commands may be used in examining the kernel and introduces the basics necessary for users to write .I adb command scripts which can augment the standard .I adb command set. The examination techniques described here may be applied both to running systems and the post-mortem dumps automatically created by the .IR savecore (8) program after a system crash. The reader is expected to have at least a passing familiarity with the debugger command language. .sp .LP Revised .AE .LP .OH 'Using ADB to Debug the Kernel''SMM:3-%' .EH 'SMM:3-%''Using ADB to Debug the Kernel' .ds RH Introduction .LP .ne 2i .NH Introduction .PP Modifications have been made to the standard VAX .UX debugger .I adb to simplify examination of post-mortem dumps automatically generated following a system crash. These changes may also be used when examining .UX in its normal operation. This document serves as an introduction to the .B use of these facilities, and should not be construed as a description of \fIhow to debug the kernel\fP. .NH 2 Invocation .PP When examining post-mortem dumps of the .UX kernel the \fB\-k\fP option should be used, e.g. .DS .cw % adb \-k vmunix.? vmcore.? .pw .DE where the appropriate version of the saved operating system image and core dump are supplied in place of ``?''. This flag causes .I adb to partially simulate the VAX virtual memory hardware when accessing the .I core file. In addition the internal state maintained by the debugger is initialized from data structures maintained by the kernel explicitly for debugging\(dd. A running kernel may be examined in a similar fashion, .DS .cw % adb \-k /vmunix /dev/mem .pw .DE .FS \(dd If the \-k flag is not used when invoking .I adb the user must explicitly calculate virtual addresses. With the .B \-k option .I adb interprets page tables to automatically perform virtual to physical address translation. .FE .NH 2 Establishing Context .PP During initialization .I adb attempts to establish the context of the ``currently active process'' by examining the value of the kernel variable \fImasterpaddr\fP. This variable contains the virtual address of the process context block of the last process which was set executing by the \fISwtch\fP routine. \fIMasterpaddr\fP normally provides sufficient information to locate the current stack frame (via the stack pointers found in the context block). By locating the process context block for the process .I adb may then perform virtual to physical address translation using that process's in-core page tables. .PP When examining post-mortem dumps locating the most recent stack frame of the last currently active process can be nontrivial. This is due to the different ways in which state may be saved after a nonrecoverable error. Crashes may or may not be ``clean'' (i.e. the top of the interrupt stack contains a pointer to the process's kernel mode stack pointer and program counter); an ``unclean'' crash will occur, for instance, if the interrupt stack overflows. When .I adb is invoked on a post-mortem crash dump it tries to automatically establish the proper stack frame. This is done by first checking the stack pointer normally saved in the restart parameter block at \fIrpb\fP+1fc (or \fIscb\fP\-4). If this value does not point to a valid stack frame, .I adb searches the interrupt stack looking for a valid stack frame. Should this also fail .I adb then searches the kernel stack located in the user structure associated with the last executing process. If .I adb is able to locate a valid stack frame using this procedure the command .DS .cw $c .pw .DE will generate a stack trace from the last point at which the kernel was executing on behalf of the user process all the way to the top of the user process's stack (e.g. to the \fImain\fP routine in the user process). Should .I adb be unable to locate a valid stack frame it prints a message and the current state is left undefined. When a stack trace of a particular process (other than that which was currently executing) is desired, an alternate method, described in \(sc2.4, should be used. .PP Additional information may be obtained from the kernel stack. Discussion of that subject is postponed until command scripts have been introduced; see \(sc2.2. .ds RH "Command Scripts .ne 2i .NH Command Scripts .NH 2 Extending the Formatting Facilities .PP Once the process context has been established, the complete .I adb command set is available for interpreting data structures. In addition, a number of .I adb scripts have been created to simplify the structured printing of commonly referenced kernel data structures. The scripts normally reside in the directory \fI/usr/lib/adb\fP, and are invoked with the ``$<'' operator. (A later table lists the standard scripts distributed with the system.) .PP As an example, consider the following listing which contains a dump of a faulty process's state (our typing is shown emboldened). .ID .DT .cw % \fBadb \-k vmunix.175 vmcore.175\fP sbr 5868 slr 2770 p0br 5a00 p0lr 236 p1br 6600 p1lr fff0 panic: dup biodone \fB$c\fP _boot() from _boot+f3 _boot(0,0) from _panic+3a _panic(800413d0) from _biodone+17 _biodone(800791e8) from _rxpurge+23 _rxpurge(80044754) from _rxstart+5a _rxstart(80044754) from 80031df8 _rxintr(0) from _Xrxintr0+11 _Xrxintr0(45b01,3aaf4) from 457f _Syssize(3aaf4) from 365a _Syssize() from 19a8 ?() from 2ff3 _Syssize(4,7fffe834) from 9cf3 _Syssize(4,7fffe834,7fffe848) from 37 ?() \fBu$l ,#l" 9 Place the value of the ``link'' in the .I adb variable ``4 *nproc>l *proc>f $l f ,#