aboutsummaryrefslogtreecommitdiff
path: root/tools/debugscripts
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugscripts')
-rw-r--r--tools/debugscripts/README20
-rw-r--r--tools/debugscripts/dot.gdbinit116
-rw-r--r--tools/debugscripts/gdbinit.i386375
-rw-r--r--tools/debugscripts/gdbinit.kernel370
-rw-r--r--tools/debugscripts/netstat-anr.gdb162
5 files changed, 1043 insertions, 0 deletions
diff --git a/tools/debugscripts/README b/tools/debugscripts/README
new file mode 100644
index 000000000000..eb301c93d993
--- /dev/null
+++ b/tools/debugscripts/README
@@ -0,0 +1,20 @@
+
+This directory contains gdb macros for kernel debugging. When you
+build a debug kernel, the target "gdbinit" in the kernel Makefile will
+create the correct .gdbinit files in the kernel build directory. To
+perform kernel debugging, you would do:
+
+ # cd /usr/obj/usr/src/sys/GENERIC (or name of kernel config)
+ # make gdbinit
+ # gdb kernel.debug
+ This GDB was configured as "i386-undermydesk-freebsd"...
+ Ready to go. Enter 'tr' to connect to remote target
+ and 'getsyms' after connection to load kld symbols.
+ (kgdb)
+
+
+This directory also contains a kgdb script that, given a crash dump number,
+automatically extracts the path to the kernel source, runs gdb to extract
+information about kernel modules loaded, and then reruns gdb loading the
+necessary symbols for the modules. You need to make sure you build the
+modules w/ debugging symbols separately to get things to work.
diff --git a/tools/debugscripts/dot.gdbinit b/tools/debugscripts/dot.gdbinit
new file mode 100644
index 000000000000..4923f2254e3b
--- /dev/null
+++ b/tools/debugscripts/dot.gdbinit
@@ -0,0 +1,116 @@
+# .gdbinit file for remote serial debugging.
+#
+# XXX Do not use this file directly. It contains parameters which are
+# XXX substituted by the kernel Makefile when you do a 'make gdbinit'.
+# XXX This also removes lines starting with '# XXX'.
+# XXX
+# To debug kernels, do:
+#
+# cd /usr/obj/usr/src/sys/GENERIC (or kernel build directory)
+# make gdbinit
+# gdb kernel.debug
+#
+# Read gdb(4) for more details.
+
+# The following lines (down to "***** End" comment) may need to be changed
+
+# Bit rate for serial link. Due to problems in the interface,
+# this may not work well above 9600 bps.
+set remotebaud 9600
+
+set output-radix 16
+set height 70
+set width 120
+set remotetimeout 1
+set complaints 1
+set print pretty
+dir ../../..
+
+# ***** End of things you're likely to need to change.
+
+# Connect to remote target via a serial port.
+define tr
+# Remote debugging port
+target remote $arg0
+end
+
+document tr
+Debug a remote system via serial or firewire interface. For example, specify 'tr /dev/cuau0' to use first serial port, or 'tr localhost:5556' for default firewire port. See also tr0, tr1 and trf commands.
+end
+
+# Convenience functions. These call tr.
+# debug via cuau0
+define tr0
+tr /dev/cuau0
+end
+define tr1
+tr /dev/cuau1
+end
+# Firewire
+define trf
+tr localhost:5556
+end
+
+document tr0
+Debug a remote system via serial interface /dev/cuau0. See also tr, tr1 and trf commands.
+end
+document tr1
+Debug a remote system via serial interface /dev/cuau1. See also tr, tr0 and trf commands.
+end
+document trf
+Debug a remote system via firewire interface at default port 5556. See also tr, tr0 and tr1 commands.
+end
+
+# Get symbols from klds. Unfortunately, there are a number of
+# landmines involved here:
+#
+# When debugging the same machine (via /dev/mem), we can get the
+# script to call kldstat and pass the info on to asf(8). This won't
+# work for crashes or remote debugging, of course, because we'd get
+# the information for the wrong system. Instead, we use the macro
+# "kldstat", which extracts the information from the "dump". The
+# trouble here is that it's a pain to use, since gdb doesn't have the
+# capability to pass data to scripts, so we have to mark it and paste
+# it into the script. This makes it silly to use this method for
+# debugging the local system. Instead, we have two scripts:
+#
+# getsyms uses the information in the "dump", and you have to paste it.
+# kldsyms uses the local kld information.
+#
+# Improvements in gdb should make this go away some day.
+#
+define kldsyms
+# This will be replaced by the path of the real modules directory.
+shell asf -f -k MODPATH
+source .asf
+end
+document kldsyms
+Read in the symbol tables for the debugging machine. This only makes sense when debugging /dev/mem; use the 'getsyms' macro for remote debugging.
+end
+
+# Remote system
+define getsyms
+kldstat
+echo Select the list above with the mouse, paste into the screen\n
+echo and then press ^D. Yes, this is annoying.\n
+# This will be replaced by the path of the real modules directory.
+shell asf -f MODPATH
+source .asf
+end
+
+document getsyms
+Display kldstat information for the target machine and invite user to paste it back in. This causes the symbols for the KLDs to be loaded. When doing memory debugging, use the command kldsyms instead.
+end
+
+source gdbinit.kernel
+source gdbinit.machine
+
+echo Ready to go. Enter 'tr' to connect to the remote target\n
+echo with /dev/cuau0, 'tr /dev/cuau1' to connect to a different port\n
+echo or 'trf portno' to connect to the remote target with the firewire\n
+echo interface. portno defaults to 5556.\n
+echo \n
+echo Type 'getsyms' after connection to load kld symbols.\n
+echo \n
+echo If you're debugging a local system, you can use 'kldsyms' instead\n
+echo to load the kld symbols. That's a less obnoxious interface.\n
diff --git a/tools/debugscripts/gdbinit.i386 b/tools/debugscripts/gdbinit.i386
new file mode 100644
index 000000000000..19c97f619a85
--- /dev/null
+++ b/tools/debugscripts/gdbinit.i386
@@ -0,0 +1,375 @@
+# Assembler-level macros for i386
+# Disassemble the next 10 instructions.
+define xi
+x/10i $eip
+end
+
+# Top 12 words on stack
+define xs
+x/12x $esp
+end
+
+# Top 12 words from frame pointer
+define xb
+x/12x $ebp
+end
+
+# single step through calls and disassemble the next instruction
+define z
+ni
+x/1i $eip
+end
+
+# single step over calls and disassemble the next instruction
+define zs
+si
+x/1i $eip
+end
+
+# show current stack frame and first 4 parameters
+define xp
+printf " esp: "
+output/x $esp
+echo (
+output (((int)$ebp)-(int)$esp)/4-4
+printf " words on stack)\n ebp: "
+output/x $ebp
+printf "\n eip: "
+x/1i $eip
+printf "Saved ebp: "
+output/x *(int*)$ebp
+printf " (maximum of "
+output ((*(int*)$ebp)-(int)$ebp)/4-4
+printf " parameters possible)\nSaved eip: "
+x/1i *(int*)($ebp+4)
+printf "\nParm 1 at "
+output/x (int) ($ebp+8)
+printf ": "
+output (char*) *(int*)($ebp+8)
+printf "\nParm 2 at "
+output/x (int) ($ebp+12)
+printf ": "
+output (char*) *(int*)($ebp+12)
+printf "\nParm 3 at "
+output/x (int) ($ebp+16)
+printf ": "
+output (char*) *(int*)($ebp+16)
+printf "\nParm 4 at "
+output/x (int) ($ebp+20)
+printf ": "
+output (char*) *(int*)($ebp+20)
+echo \n
+end
+document xp
+Show the register contents and the first four parameter
+words of the current frame.
+end
+
+# show current stack frame and first 10 parameters
+define xxp
+printf " esp: "
+output/x $esp
+printf "\n ebp: "
+output/x $ebp
+printf "\n eip: "
+x/1i $eip
+printf "Saved ebp: "
+output/x *(int*)$ebp
+printf " (maximum of "
+output ((*(int*)$ebp)-(int)$ebp)/4-4
+printf " parameters possible)\nSaved eip: "
+x/1i *(int*)($ebp+4)
+printf "\nParm 1 at "
+output/x (int) ($ebp+8)
+printf ": "
+output (char*) *(int*)($ebp+8)
+printf "\nParm 2 at "
+output/x (int) ($ebp+12)
+printf ": "
+output (char*) *(int*)($ebp+12)
+printf "\nParm 3 at "
+output/x (int) ($ebp+16)
+printf ": "
+output (char*) *(int*)($ebp+16)
+printf "\nParm 4 at "
+output/x (int) ($ebp+20)
+printf ": "
+output (char*) *(int*)($ebp+20)
+printf "\nParm 5 at "
+output/x (int) ($ebp+24)
+printf ": "
+output (char*) *(int*)($ebp+24)
+printf "\nParm 6 at "
+output/x (int) ($ebp+28)
+printf ": "
+output (char*) *(int*)($ebp+28)
+printf "\nParm 7 at "
+output/x (int) ($ebp+32)
+printf ": "
+output (char*) *(int*)($ebp+32)
+printf "\nParm 8 at "
+output/x (int) ($ebp+36)
+printf ": "
+output (char*) *(int*)($ebp+36)
+printf "\nParm 9 at "
+output/x (int) ($ebp+40)
+printf ": "
+output (char*) *(int*)($ebp+40)
+printf "\nParm 10 at "
+output/x (int) ($ebp+44)
+printf ": "
+output (char*) *(int*)($ebp+44)
+echo \n
+end
+document xxp
+Show the register contents and the first ten parameter
+words of the current frame.
+end
+
+# Show first to fifth parameters of current frame as int, int * and char *.
+define xp0
+x/12x *(int*)$esp
+p *(int*)$esp
+p (char*)*$esp
+end
+define xp1
+x/12x *(int*)($ebp+4)
+p *(int*)($ebp+4)
+p (char**)($ebp+4)
+end
+define xp2
+x/12x *(int*)($ebp+8)
+p *(int*)($ebp+8)
+p *(char**)($ebp+8)
+end
+define xp3
+x/12x *(int*)($ebp+12)
+p *(int*)($ebp+12)
+p (char**)($ebp+12)
+end
+define xp4
+x/12x *(int*)($ebp+16)
+p *(int*)($ebp+16)
+p (char**)($ebp+16)
+end
+document xp0
+Show the first parameter of current stack frame in various formats
+end
+document xp1
+Show the second parameter of current stack frame in various formats
+end
+document xp2
+Show the third parameter of current stack frame in various formats
+end
+document xp3
+Show the fourth parameter of current stack frame in various formats
+end
+document xp4
+Show the fifth parameter of current stack frame in various formats
+end
+
+# Select frame 0 to 5 and show stack information.
+define f0
+f 0
+xp
+end
+define f1
+f 1
+xp
+end
+define f2
+f 2
+xp
+end
+define f3
+f 3
+xp
+end
+define f4
+f 4
+xp
+end
+define f5
+f 5
+xp
+end
+document f0
+Select stack frame 0 and show assembler-level details
+end
+document f1
+Select stack frame 1 and show assembler-level details
+end
+document f2
+Select stack frame 2 and show assembler-level details
+end
+document f3
+Select stack frame 3 and show assembler-level details
+end
+document f4
+Select stack frame 4 and show assembler-level details
+end
+document f5
+Select stack frame 5 and show assembler-level details
+end
+document z
+Single step 1 instruction (over calls) and show next instruction.
+end
+document zs
+Single step 1 instruction (through calls) and show next instruction.
+end
+document xi
+List the next 10 instructions from the current IP value
+end
+document xs
+Show the last 12 words on stack in hex
+end
+document xb
+Show 12 words starting at current BP value in hex
+end
+
+# pcb <pid>
+# show contents of pcb, currently only i386.
+define pcb
+ set $nproc = nprocs
+ set $aproc = allproc.lh_first
+ set $proc = allproc.lh_first
+ while (--$nproc >= 0)
+ set $pptr = $proc.p_pptr
+ if ($proc->p_pid == $arg0)
+ set $pcba = $proc->p_threads.tqh_first->td_pcb
+ printf "ip: %08x sp: %08x bp: %08x bx: %08x\n", $pcba->pcb_eip, $pcba->pcb_esp, $pcba->pcb_ebp, $pcba->pcb_ebx
+ x/1i $pcba->pcb_eip
+ set $nproc = 0
+ end
+ set $aproc = $proc.p_list.le_next
+ if ($aproc == 0 && $nproc > 0)
+ set $aproc = zombproc
+ end
+ set $proc = $aproc
+ end
+end
+document pcb
+Show some pcb contents of process whose pid is specified.
+end
+
+# btr <frame>
+# primitive backtrace. frame is a memory address.
+define btr
+set $frame = $arg0
+set $fno = 0
+while (*(int *) $frame > 0xc0000000)
+ set $myebp = *(int *) $frame
+ set $myeip = *(int *) ($frame + 4)
+ printf " frame %d at %p: ebp %8x, eip ", $fno, $frame, $myebp
+ x/1i $myeip
+ set $frame = $myebp
+ set $fno = $fno + 1
+end
+end
+document btr
+Show a backtrace from the ebp address specified. This can be used to get a backtrace from any stack resident in memory. It's the user's responsibility to ensure that the address is meaningful.
+end
+
+# btp <pid>
+# backtrace for process <pid>. Uses btr (machine dependent) to perform the backtrace.
+# may produce nonsense.
+define btp
+ set $nproc = nprocs
+ set $aproc = allproc.lh_first
+ set $proc = allproc.lh_first
+ while (--$nproc >= 0)
+ if ($proc->p_pid == $arg0)
+ btr $proc->p_threads.tqh_first->td_pcb->pcb_ebp
+ set $nproc = 0
+ else
+ set $aproc = $proc.p_list.le_next
+ if ($aproc == 0 && $nproc > 0)
+ set $aproc = zombproc
+ end
+ set $proc = $aproc
+ end
+ end
+end
+document btp
+Show a backtrace for the process whose pid is specified as a parameter.
+end
+
+# Do backtraces for all processes in the system.
+# Uses btr (machine dependent) to perform the backtrace.
+define btpa
+ set $nproc = nprocs
+ set $aproc = allproc.lh_first
+ set $proc = allproc.lh_first
+ printf " pid proc uid ppid pgrp flag stat comm wchan\n"
+ while (--$nproc >= 0)
+ set $pptr = $proc.p_pptr
+ if ($pptr == 0)
+ set $pptr = $proc
+ end
+ if ($proc.p_stat)
+ printf "%5d %08x %4d %5d %5d %06x %d %-10s ", \
+ $proc.p_pid, $aproc, \
+ $proc.p_cred->p_ruid, $pptr->p_pid, \
+ $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_stat, \
+ &$proc.p_comm[0]
+ if ($proc.p_wchan)
+ if ($proc.p_wmesg)
+ printf "%s ", $proc.p_wmesg
+ end
+ printf "%x", $proc.p_wchan
+ end
+ printf "\n"
+ if ($proc->p_flag & 4)
+ btr $proc->p_threads.tqh_first->td_pcb->pcb_ebp
+ else
+ echo (not loaded)\n
+ end
+ end
+ set $aproc = $proc.p_list.le_next
+ if ($aproc == 0 && $nproc > 0)
+ set $aproc = zombproc
+ end
+ set $proc = $aproc
+ end
+end
+document btpa
+Show backtraces for all processes in the system.
+end
+
+# Show backtrace for process selected with "defproc"
+define btpp
+btr $myvectorproc->p_threads.tqh_first->td_pcb->pcb_ebp
+end
+document btpp
+Show a backtrace for the process previously selected with 'defproc'.
+end
+
+# Specific stack fram of process selected with "defproc".
+define fr
+set $fno = 0
+set $searching = 1
+set $frame = $myvectorproc->p_threads.tqh_first->td_pcb->pcb_ebp
+while (($searching == 1) && (*(int *) $frame > 0xc0000000))
+ set $myebp = *(int *) $frame
+ set $myeip = *(int *) ($frame + 4)
+ if ($fno == $arg0)
+ printf " frame %d at %p: ebp %8x, eip ", $fno, $frame, $myebp
+ x/1i $myeip
+ printf "Called from %8x, stack frame at %8x\n", *(int *) ($myebp+4), *(int *) $myebp
+ printf "last 20 local variables:\n"
+ x/20x ($myebp-80)
+ printf "call parameters:\n"
+ x/8x ($myebp+8)
+ set $searching = 0
+ else
+ set $frame = $myebp
+ set $fno = $fno + 1
+ end
+end
+if ($searching == 1)
+ echo frame not found\n
+end
+end
+document fr
+Show the frame of the stack of the process previously selected with 'defproc'.
+end
diff --git a/tools/debugscripts/gdbinit.kernel b/tools/debugscripts/gdbinit.kernel
new file mode 100644
index 000000000000..5fa3efc7e7df
--- /dev/null
+++ b/tools/debugscripts/gdbinit.kernel
@@ -0,0 +1,370 @@
+# General kernel macros
+
+# Print the command name of the current process
+define pname
+p (char *)curproc->p_comm
+end
+document pname
+Print the command name of the current process.
+end
+
+# Show contents of bp supplied as first parameter:
+#
+# (gdb) bpp bp
+define bpp
+set $bp = (struct buf *) $arg0
+ if $bp->b_io.bio_dev
+ printf " Buffer at 0x%x: dev 0x%x data 0x%x bcount 0x%x blkno 0x%x resid 0x%x\n", \
+ $bp, \
+ $bp->b_io.bio_dev->si_udev, \
+ $bp->b_io.bio_data, \
+ $bp->b_io.bio_bcount, \
+ $bp->b_io.bio_blkno, \
+ $bp->b_io.bio_resid
+ else
+ printf " Buffer at 0x%x: dev (none) data 0x%x bcount 0x%x blkno 0x%x resid 0x%x\n", \
+ $bp, \
+ $bp->b_io.bio_data, \
+ $bp->b_io.bio_bcount, \
+ $bp->b_io.bio_blkno, \
+ $bp->b_io.bio_resid
+ end
+ printf " flags 0x%x: ", $bp->b_flags
+ if $bp->b_flags & 0x10
+ printf "busy "
+ end
+ if $bp->b_flags & 0x40
+ printf "call "
+ end
+ if $bp->b_flags & 0x200
+ printf "done "
+ end
+ if $bp->b_flags & 0x800
+ printf "error "
+ end
+ if $bp->b_flags & 0x40000
+ printf "phys "
+ end
+ if $bp->b_flags & 0x100000
+ printf "read "
+ end
+ printf "\n"
+end
+document bpp
+Show summary information about the buffer header (struct bp) pointed at by the parameter.
+end
+
+# Show more detailed contents of bp supplied as first parameter:
+#
+# (gdb) bpl bp
+define bpl
+set $bp = (struct buf *) $arg0
+printf "b_proc: "
+output $bp->b_proc
+printf "\nb_flags: "
+output $bp->b_flags
+printf "\nb_qindex: "
+output $bp->b_qindex
+printf "\nb_usecount: "
+output $bp->b_usecount
+printf "\nb_error: "
+output $bp->b_error
+printf "\nb_bufsize: "
+output $bp->b_bufsize
+printf "\nb_io.bio_bcount: "
+output $bp->b_io.bio_bcount
+printf "\nb_io.bio_resid: "
+output $bp->b_io.bio_resid
+printf "\nb_io.bio_dev: "
+output $bp->b_io.bio_dev
+printf "\nb_io.bio_data: "
+output $bp->b_io.bio_data
+printf "\nb_kvasize: "
+output $bp->b_kvasize
+printf "\nb_lblkno: "
+output $bp->b_lblkno
+printf "\nb_io.bio_blkno: "
+output $bp->b_io.bio_blkno
+printf "\nb_iodone: "
+output $bp->b_iodone
+printf "\nb_vp: "
+output $bp->b_vp
+printf "\nb_dirtyoff: "
+output $bp->b_dirtyoff
+printf "\nb_dirtyend: "
+output $bp->b_dirtyend
+printf "\nb_generation: "
+output $bp->b_generation
+printf "\nb_rcred: "
+output $bp->b_rcred
+printf "\nb_wcred: "
+output $bp->b_wcred
+printf "\nb_validoff: "
+output $bp->b_validoff
+printf "\nb_validend: "
+output $bp->b_validend
+printf "\nb_pblkno: "
+output $bp->b_pblkno
+printf "\nb_saveaddr: "
+output $bp->b_saveaddr
+printf "\nb_savekva: "
+output $bp->b_savekva
+printf "\nb_driver1: "
+output $bp->b_driver1
+printf "\nb_driver2: "
+output $bp->b_driver2
+printf "\nb_spc: "
+output $bp->b_spc
+printf "\nb_npages: "
+output $bp->b_npages
+printf "\n"
+end
+document bpl
+Show detailed information about the buffer header (struct bp) pointed at by the parameter.
+end
+
+# Show contents of buffer header in local variable bp.
+define bp
+bpp bp
+end
+document bp
+Show information about the buffer header pointed to by the variable bp in the current frame.
+end
+
+# Show data of buffer header in local variable bp as string.
+define bpd
+ printf "Buffer data:\n%s", (char *) bp->b_io.bio_data
+end
+document bpd
+Show the contents (char*) of bp->data in the current frame.
+end
+document bpl
+Show detailed information about the buffer header (struct bp) pointed at by the local variable bp.
+end
+define bx
+printf "\n b_vnbufs "
+output/x bp->b_vnbufs
+printf "\n b_freelist "
+output/x bp->b_freelist
+printf "\n b_act "
+output/x bp->b_act
+printf "\n b_flags "
+output/x bp->b_flags
+printf "\n b_qindex "
+output/x bp->b_qindex
+printf "\n b_usecount "
+output/x bp->b_usecount
+printf "\n b_error "
+output/x bp->b_error
+printf "\n b_bufsize "
+output/x bp->b_bufsize
+printf "\n b_io.bio_bcount "
+output/x bp->b_io.bio_bcount
+printf "\n b_io.bio_resid "
+output/x bp->b_io.bio_resid
+printf "\n b_io.bio_dev "
+output/x bp->b_io.bio_dev
+printf "\n b_io.bio_data "
+output/x bp->b_io.bio_data
+printf "\n b_kvasize "
+output/x bp->b_kvasize
+printf "\n b_io.bio_blkno "
+output/x bp->b_io.bio_blkno
+printf "\n b_iodone_chain "
+output/x bp->b_iodone_chain
+printf "\n b_vp "
+output/x bp->b_vp
+printf "\n b_dirtyoff "
+output/x bp->b_dirtyoff
+printf "\n b_validoff "
+output/x bp->b_validoff
+echo \n
+end
+document bx
+Print a number of fields from the buffer header pointed at in by the pointer bp in the current environment.
+end
+
+# Switch back to ddb
+define ddb
+set boothowto=0x80000000
+s
+end
+document ddb
+Switch back to ddb.
+end
+
+# ps: equivalent of the userland command
+define ps
+ set $nproc = nprocs
+ set $aproc = allproc.lh_first
+ set $proc = allproc.lh_first
+ set $tid = 1
+ printf "pid/ID ppid/tid uid pgrp flag st comm/name proc/thread\n"
+ while (--$nproc >= 0)
+ set $pptr = $proc.p_pptr
+ if ($pptr == 0)
+ set $pptr = $proc
+ end
+ if ($proc.p_state)
+ printf " %5d %6d %4d %5d %8x %2d %-10s %p\n", \
+ $proc.p_pid, $pptr->p_pid, \
+ $proc.p_ucred->cr_ruid, \
+ $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_state, \
+ &$proc.p_comm[0], $aproc
+ set $thread = $proc->p_threads.tqh_first
+ while ($thread)
+ printf "(%5d) %6d %-10s %p", \
+ $tid, $thread->td_tid, $thread->td_name, $thread
+ if ($thread.td_wmesg)
+ printf " %s", $thread.td_wmesg
+ end
+ printf "\n"
+ set $thread = $thread->td_plist.tqe_next
+ set $tid = $tid + 1
+ end
+ end
+ set $aproc = $proc.p_list.le_next
+ if ($aproc == 0 && $nproc > 0)
+ set $aproc = zombproc
+ end
+ set $proc = $aproc
+ end
+end
+document ps
+Show process status without options.
+end
+
+# Specify a process for other commands to refer to.
+# Most are machine-dependent.
+define defproc
+ set $nproc = nprocs
+ set $aproc = allproc.lh_first
+ set $proc = allproc.lh_first
+ while (--$nproc >= 0)
+ if ($proc->p_pid == $arg0)
+ set $pptr = $proc.p_pptr
+ if ($pptr == 0)
+ set $pptr = $proc
+ end
+ set $myvectorproc = $proc
+ if ($proc.p_state)
+ set $thread = $proc->p_threads.tqh_first
+ while ($thread)
+ printf "%5d %08x %08x %4d %5d %5d %06x %d %-10s ", \
+ $proc.p_pid, $aproc, \
+ $proc.p_uarea, $proc.p_ucred->cr_ruid, $pptr->p_pid, \
+ $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_state, \
+ &$proc.p_comm[0]
+ if ($thread.td_wchan)
+ if ($thread.td_wmesg)
+ printf "%s ", $thread.td_wmesg
+ end
+ printf "%x", $thread.td_wchan
+ end
+ printf "\n"
+ set $thread = $thread->td_plist.tqe_next
+ end
+ end
+ btpp
+ set $nproc = 0
+ else
+ set $proc = $proc.p_list.le_next
+ end
+ end
+end
+document defproc
+Specify a process for btpp and fr commands.
+end
+
+define vdev
+if (vp->v_type == VBLK)
+ p *vp->v_un.vu_spec.vu_specinfo
+ printf "numoutput: %d\n", vp->v_numoutput
+else
+ echo "Not a block device"
+end
+end
+document vdev
+Show some information of the vnode pointed to by the local variable vp.
+end
+
+# Kludge. When changing macros, it's convenient to copy and paste
+# definitions from the editor into the debugger window.
+# Unfortunately, gdb insists on asking for confirmation after the
+# "define" line. y enables you to insert the confirmation in the
+# definition without affecting the way the macro runs (much).
+define y
+echo Check your .gdbinit: it contains a y command\n
+end
+
+document y
+Kludge for writing macros This is a no-op except for printing a message See gdb(4) for more details.
+end
+
+# dmesg: print msgbuf. Can take forever.
+define dmesg
+printf "%s", msgbufp->msg_ptr
+end
+document dmesg
+Print the system message buffer (dmesg) This can take a long time due to the time it takes to transmit the data across a serial line and even on a firewire connection the processing time slows it down
+end
+
+# checkmem: check unallocated memory for modifications
+# this assumes that DIAGNOSTIC is set, which causes
+# free memory to be set to 0xdeadc0de
+#
+# Use: checkmem offset length
+define checkmem
+set $offset = $arg0
+# XXX sizeof int. Needs changing for 64 bit machines.
+# subtract 1 because the last word is always different.
+set $length = $arg1 / 4 - 1
+set $word = 0
+while ($word < $length)
+ if ((int *) $offset) [$word] != 0xdeadc0de
+ printf "invalid word 0x%x at 0x%x\n", ((int *) $offset) [$word], &((int *) $offset) [$word]
+ end
+ set $word = $word + 1
+end
+end
+
+document checkmem
+Check unallocated memory for modifications This assumes that DIAGNOSTIC is set which causes free memory to be set to 0xdeadc0de.
+end
+
+define kernel
+ exec-file kernel.$arg0
+ symbol-file symbols.$arg0
+ core-file vmcore.$arg0
+end
+
+define kldstat
+ set $kld = linker_files.tqh_first
+ printf "Id Refs Address Size Name\n"
+ while ($kld != 0)
+ printf "%2d %4d 0x%08x %-8x %s\n", \
+ $kld->id, $kld->refs, $kld->address, $kld->size, $kld->filename
+ set $kld = $kld->link.tqe_next
+ end
+end
+
+document kldstat
+ Lists the modules that were loaded when the kernel crashed.
+end
+
+define kldstat-v
+ set $kld = linker_files.tqh_first
+ printf "Id Refs Address Size Name\n"
+ while ($kld != 0)
+ printf "%2d %4d 0x%08x %-8x %s\n", \
+ $kld->id, $kld->refs, $kld->address, $kld->size, $kld->filename
+ printf " Contains modules:\n"
+ printf " Id Name\n"
+ set $module = $kld->modules.tqh_first
+ while ($module != 0)
+ printf " %2d %s\n", $module->id, $module->name
+ set $module = $module->link.tqe_next
+ end
+ set $kld = $kld->link.tqe_next
+ end
+end
diff --git a/tools/debugscripts/netstat-anr.gdb b/tools/debugscripts/netstat-anr.gdb
new file mode 100644
index 000000000000..2c1faaf86a98
--- /dev/null
+++ b/tools/debugscripts/netstat-anr.gdb
@@ -0,0 +1,162 @@
+#
+#
+
+document netstat-anr
+Print routing tables as 'netstat -anr' does.
+end
+
+set $debug = 0
+
+set $AF_INET = 2
+set $AF_LINK = 18
+
+set $RNF_ROOT = 2
+set $RNF_ACTIVE = 4
+
+set $RTF_UP = 0x1
+set $RTF_GATEWAY = 0x2
+set $RTF_HOST = 0x4
+set $RTF_STATIC = 0x800
+
+#
+# XXX: alas, we can't script "show endian"
+#
+if (machine[0] == 'a' && machine[1] == 'm' && machine[2] == 'd') || \
+ (machine[0] == 'i' && machine[1] == '3' && machine[2] == '8')
+ set $byteswap = 1
+else
+ set $byteswap = 0
+end
+
+define routename
+ if ($byteswap)
+ printf "%u.%u.%u.%u", \
+ $arg0 & 0xff, ($arg0 >> 8) & 0xff, \
+ ($arg0 >> 16) & 0xff, ($arg0 >> 24) & 0xff
+ else
+ printf "%u.%u.%u.%u", \
+ ($arg0 >> 24) & 0xff, ($arg0 >> 16) & 0xff, \
+ ($arg0 >> 8) & 0xff, $arg0 & 0xff
+ end
+end
+
+define domask
+ set $i = 0
+ set $b = 0
+ while $b < 32
+ if ($arg0 & (1 << $b))
+ set $i = $i + 1
+ end
+ set $b = $b + 1
+ end
+ printf "/%d", $i
+end
+
+define p_flags
+ if ($arg0 & $RTF_UP)
+ printf "U"
+ end
+ if ($arg0 & $RTF_GATEWAY)
+ printf "G"
+ end
+ if ($arg0 & $RTF_HOST)
+ printf "H"
+ end
+ if ($arg0 & $RTF_STATIC)
+ printf "S"
+ end
+end
+
+define p_sockaddr
+ set $sa = (struct sockaddr *)$arg0
+ set $flags = $arg2
+ if ($sa->sa_family == $AF_INET)
+ set $sin = (struct sockaddr_in *)$arg0
+ set $mask = (struct sockaddr_in *)$arg1
+ if ($flags & $RTF_HOST)
+ routename $sin->sin_addr.s_addr
+ else
+ routename $sin->sin_addr.s_addr
+ if ($mask != 0)
+ domask $mask->sin_addr.s_addr
+ else
+ domask 0
+ end
+ end
+ end
+ if ($sa->sa_family == $AF_LINK)
+ set $sdl = (struct sockaddr_dl *)$arg0
+ if ($sdl->sdl_nlen == 0 && $sdl->sdl_alen == 0 && \
+ $sdl->sdl_slen == 0)
+ printf "link#%d", $sdl->sdl_index
+ end
+ end
+end
+
+define p_rtentry
+ set $rte = (struct rtentry *)$arg0
+ set $rn = (struct radix_node *)$arg0
+ set $sa = ((struct sockaddr **)($rn->rn_u.rn_leaf.rn_Key))
+ set $sam = ((struct sockaddr **)($rn->rn_u.rn_leaf.rn_Mask))
+ set $gw = $rte->rt_gateway
+
+ p_sockaddr $sa $sam $rte->rt_flags
+ printf "\t"
+ p_sockaddr $gw 0 $RTF_HOST
+ printf "\t"
+ p_flags $rte->rt_flags
+ printf "\t"
+ if ($rte->rt_ifp != 0)
+ printf "%s", $rte->rt_ifp->if_xname
+ end
+ printf "\n"
+end
+
+define p_rtree
+ set $rn_$arg0 = (struct radix_node *)$arg1
+ set $left_$arg0 = $arg0 + 1
+ set $right_$arg0 = $arg0 + 2
+ set $duped_$arg0 = $arg0 + 3
+
+ if ($rn_$arg0->rn_bit < 0 || ($rn_$arg0->rn_flags & $RNF_ACTIVE) == 0)
+ if ($debug == 1)
+ printf "print "
+ p $rn_$arg0
+ end
+ if (($rn_$arg0->rn_flags & ($RNF_ACTIVE | $RNF_ROOT)) == \
+ $RNF_ACTIVE)
+ p_rtentry $rn_$arg0
+ end
+ if (($rn_$arg0->rn_flags & $RNF_ACTIVE) != 0 && \
+ $rn_$arg0->rn_u.rn_leaf.rn_Dupedkey != 0)
+ if ($debug == 1)
+ printf "duped "
+ p $rn_$arg0
+ end
+ p_rtree $duped_$arg0 $rn_$arg0->rn_u.rn_leaf.rn_Dupedkey
+ end
+ else
+ if ($rn_$arg0->rn_u.rn_node.rn_R != 0)
+ if ($debug == 1)
+ printf "right "
+ p $rn_$arg0
+ end
+ p_rtree $right_$arg0 $rn_$arg0->rn_u.rn_node.rn_R
+ end
+ if ($rn_$arg0->rn_u.rn_node.rn_L != 0)
+ if ($debug == 1)
+ printf "left "
+ p $rn_$arg0
+ end
+ p_rtree $left_$arg0 $rn_$arg0->rn_u.rn_node.rn_L
+ end
+ end
+end
+
+define netstat-anr
+ printf "Routing tables\n\nInternet:\n"
+ set $af = $AF_INET
+ set $rt = (struct radix_node_head **)rt_tables + $af
+ printf "Destination\tGateway\tFlags\tNetif\n"
+ p_rtree 0 $rt->rnh_treetop
+end