aboutsummaryrefslogtreecommitdiff
path: root/tools/debugscripts
diff options
context:
space:
mode:
authorGreg Lehey <grog@FreeBSD.org>2003-06-07 01:01:42 +0000
committerGreg Lehey <grog@FreeBSD.org>2003-06-07 01:01:42 +0000
commit030b9a7c93cba8856f6795c28fc68003f855a9b1 (patch)
treee1e17464ea5d95bbb669c741100eec50b166a09a /tools/debugscripts
parent2fb00a3eaa4f429e83720636fccabaf8cba6d3ed (diff)
downloadsrc-030b9a7c93cba8856f6795c28fc68003f855a9b1.tar.gz
src-030b9a7c93cba8856f6795c28fc68003f855a9b1.zip
Add macros for kernel debugging. These have been around for a
while, and they will need some more tuning before they're really useful, but at the moment they're better than nothing. Indirectly reminded by: dwhite
Notes
Notes: svn path=/head/; revision=115926
Diffstat (limited to 'tools/debugscripts')
-rw-r--r--tools/debugscripts/dot.gdbinit44
-rw-r--r--tools/debugscripts/gdbinit.i386386
-rw-r--r--tools/debugscripts/gdbinit.kernel340
-rw-r--r--tools/debugscripts/gdbinit.vinum334
4 files changed, 1104 insertions, 0 deletions
diff --git a/tools/debugscripts/dot.gdbinit b/tools/debugscripts/dot.gdbinit
new file mode 100644
index 000000000000..c150d6484ebb
--- /dev/null
+++ b/tools/debugscripts/dot.gdbinit
@@ -0,0 +1,44 @@
+# $FreeBSD$
+# .gdbinit file for remote serial debugging.
+# see gdbinit(9) for further details.
+#
+# The following lines (down to "end" comment) may need to be changed
+file kernel.debug
+set output-radix 16
+set height 70
+set width 120
+
+# Connect to remote target
+define tr
+set remotebaud 9600
+# Remote debugging port
+target remote /dev/cuaa0
+end
+
+# Get symbols from klds. This is a little fiddly, but very fast.
+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 should be the path of the real modules directory.
+shell asf modules/src/FreeBSD/5-CURRENT-ZAPHOD/src/sys/modules
+source .asf
+end
+
+# End of things you're likely to need to change.
+
+set remotetimeout 1
+set complaints 1
+set print pretty
+dir ../../..
+document tr
+Attach to a remote kernel via serial port
+end
+
+source gdbinit.kernel
+source gdbinit.vinum
+
+# Attach to the remote kernel
+tr
+# And get the symbols from klds
+getsyms
diff --git a/tools/debugscripts/gdbinit.i386 b/tools/debugscripts/gdbinit.i386
new file mode 100644
index 000000000000..26b569e3d797
--- /dev/null
+++ b/tools/debugscripts/gdbinit.i386
@@ -0,0 +1,386 @@
+# $FreeBSD$
+# 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
+y
+ 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 responsiblity 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
+y
+ 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 addr 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 %08x %4d %5d %5d %06x %d %-10s ", \
+ $proc.p_pid, $aproc, \
+ $proc.p_uarea, $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
+ if ($myvectorproc->p_flag & 4)
+ btr $myvectorproc->p_threads.tqh_first->td_pcb->pcb_ebp
+ else
+ echo (not loaded)\n
+ end
+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
+if ($myvectorproc->p_flag & 4)
+ 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
+else
+ printf "process %d is not loaded in memory\n", $myvectorproc->p_pid
+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..f0db297b11b0
--- /dev/null
+++ b/tools/debugscripts/gdbinit.kernel
@@ -0,0 +1,340 @@
+# $FreeBSD$
+# 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 detailled 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
+
+# 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
+ printf " pid proc addr 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_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
+ 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. No 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_stat)
+ printf "%5d %08x %08x %4d %5d %5d %06x %d %-10s ", \
+ $proc.p_pid, $aproc, \
+ $proc.p_uarea, $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"
+ 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
+
+# kldstat(1) lookalike
+define kldstat
+ set $file = linker_files.tqh_first
+ printf "Id Refs Address Size Name\n"
+ while ($file != 0)
+ printf "%2d %4d 0x%8x %8x %s\n", \
+ $file->id, \
+ $file->refs, \
+ $file->address, \
+ $file->size, \
+ $file->filename
+ set $file = $file->link.tqe_next
+ end
+end
+document kldstat
+Equivalent of the kldstat(9) command, without options.
+end
+
+# msgbuf: print msgbuf. Can take forever.
+define msgbuf
+printf "%s", msgbufp->msg_ptr
+end
+document msgbuf
+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.
+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
diff --git a/tools/debugscripts/gdbinit.vinum b/tools/debugscripts/gdbinit.vinum
new file mode 100644
index 000000000000..7ddfb5e98944
--- /dev/null
+++ b/tools/debugscripts/gdbinit.vinum
@@ -0,0 +1,334 @@
+# $FreeBSD$
+# gdb macros for debugging Vinum.
+# This file gets included from the .gdbinit files in
+# the kernel build directory and /var/crash.
+# Normally you won't need to include it directly.
+# see gdbinit(9) for further details.
+
+# Show information about the request pointed to by the variable rq in the current frame.
+define rq
+rqq rq
+end
+document rq
+Show information about the request pointed to by the variable rq in the current frame.
+end
+
+# Show information about the request (struct rq) pointed at by the parameter
+define rqq
+set $rq = (struct request *) $arg0
+printf "Request: \n"
+output/x *$rq
+printf "\n"
+bpp $rq->bp
+set $rqg = $rq->rqg
+while ($rqg != 0)
+ printf "\nRequest group at %x:\n", $rqg
+ output/x *$rqg
+ printf "\n"
+ set $rqno = 0
+ while ($rqno < $rqg->count)
+ printf "rqg->rqe [%d]: ", $rqno
+ rrqe &$rqg->rqe[$rqno]
+ set $rqno = $rqno + 1
+ end
+ set $rqg = $rqg->next
+ end
+end
+document rqq
+Show information about the request (struct rq) pointed at by the parameter
+end
+
+# Show information about the request element pointed to by the variable rqe in the current frame.
+define rqe
+rrqe rqe
+end
+document rqe
+Show information about the request element pointed to by the variable rqe in the current frame.
+end
+
+# Show information about the request element (struct rqe) pointed at by the parameter.
+define rrqe
+set $rqe = (struct rqelement *) $arg0
+ printf "sdoffset 0x%x, useroffset 0x%x, dataoffset 0x%x, datalen 0x%x, groupoffset 0x%x, grouplen 0x%x, buflen 0x%x\n", \
+ $rqe->sdoffset, \
+ $rqe->useroffset, \
+ $rqe->dataoffset, \
+ $rqe->datalen, \
+ $rqe->groupoffset, \
+ $rqe->grouplen, \
+ $rqe->buflen
+ printf " Flags 0x%x, Subdisk %d Drive %d\n", \
+ $rqe->flags, \
+ $rqe->sdno, \
+ $rqe->driveno
+ bpp &$rqe->b
+end
+document rrqe
+Show information about the request element (struct rqe) pointed at by the parameter.
+end
+
+define rqq0
+printf "rq->prq [0].rqe[0].sdno: "
+output/x rq->prq[0].rqe[0].sdno
+printf "\nBuffer: device: "
+output/x rq->prq[0].rqe[0].b.b_dev
+printf " data: "
+output/x rq->prq[0].rqe[0].b.b_data
+printf " length: "
+output/x rq->prq[0].rqe[0].b.b_bcount
+printf " drive offset: "
+output/x rq->prq[0].rqe[0].b.b_blkno
+printf " subdisk offset: "
+output/x rq->prq[0].rqe[0].sdoffset
+printf "\nFlags: "
+if (rq->prq[0].rqe[0].b.b_flags & 0x10)
+printf "busy "
+end
+if (rq->prq[0].rqe[0].b.b_flags & 0x200)
+printf "done "
+end
+if (rq->prq[0].rqe[0].b.b_flags & 0x800)
+printf "error "
+end
+if (rq->prq[0].rqe[0].b.b_flags & 0x100000)
+printf "read "
+end
+output/x rq->prq[0].rqe[0].b.b_flags
+printf "\nrq->prq [0].rqe[1].sdno: "
+output/x rq->prq[0].rqe[1].sdno
+printf "\nBuffer: device: "
+output/x rq->prq[0].rqe[1].b.b_dev
+printf " data: "
+output/x rq->prq[0].rqe[1].b.b_data
+printf " length: "
+output/x rq->prq[0].rqe[1].b.b_bcount
+printf " drive offset: "
+output/x rq->prq[0].rqe[1].b.b_blkno
+printf " subdisk offset: "
+output/x rq->prq[0].rqe[1].sdoffset
+printf "\nFlags: "
+output/x rq->prq[0].rqe[1].b.b_flags
+echo \n
+end
+define rqq1
+printf "\nrq->prq [1].rqe[0].sdno: "
+output/x rq->prq[1].rqe[0].sdno
+printf "\nBuffer: device: "
+output/x rq->prq[1].rqe[0].b.b_dev
+printf " data: "
+output/x rq->prq[1].rqe[0].b.b_data
+printf " length: "
+output/x rq->prq[1].rqe[0].b.b_bcount
+printf " drive offset: "
+output/x rq->prq[1].rqe[0].b.b_blkno
+printf " subdisk offset: "
+output/x rq->prq[1].rqe[0].sdoffset
+printf "\nFlags: "
+output/x rq->prq[1].rqe[0].b.b_flags
+printf "\nrq->prq [1].rqe[1].sdno: "
+output/x rq->prq[1].rqe[1].sdno
+printf "\nBuffer: device: "
+output/x rq->prq[1].rqe[1].b.b_dev
+printf " data: 0x%x length 0x%x drive offset 0x%x sd offset 0x%x\n" rq->prq[1].rqe[1].b.b_data,
+ rq->prq[1].rqe[1].b.b_bcount,
+ rq->prq[1].rqe[1].b.b_blkno,
+ rq->prq[1].rqe[1].sdoffset
+printf "\nFlags: "
+output/x rq->prq[1].rqe[1].b.b_flags
+echo \n
+end
+define xy
+bpp
+echo stripeoffset
+p stripeoffset
+echo stripebase
+p stripebase
+echo sdno
+p sdno
+echo sdoffset
+p sdoffset
+echo rqe->sectors
+p rqe->sectors
+echo rqe->sdoffset
+p rqe->sdoffset
+end
+# kernel equivalent of 'info -V'
+define rqi
+ set $rqipe = rqip
+ set $rqip = $rqipe + 1
+ set $rqend = rqinfo + 128
+ if ($rqip == $rqend)
+ set $rqip = rqinfo
+ end
+ set $done = 0
+ while ($done == 0)
+ if ($rqip->bp != 0)
+ printf "%X:\t%d.%06d\tUBP: %x\t", $rqip, $rqip->timestamp.tv_sec, $rqip->timestamp.tv_usec, $rqip->bp
+ p $rqip->type
+ printf " user "
+ bpp $rqip->bp
+ if ($rqip->type < loginfo_rqe)
+ printf " copied"
+ bpp &$rqip->info
+ else
+ rrqe &$rqip->info
+ end
+ end
+ set $rqip = $rqip + 1
+ if ($rqip == $rqipe)
+ set $done = 1
+ end
+ if ($rqip == $rqend)
+ set $rqip = rqinfo
+ end
+ end
+end
+define rqinfo
+ set $rqipe = rqip
+ set $rqip = $rqipe + 1
+ set $rqend = rqinfo + 128
+ if ($rqip == $rqend)
+ set $rqip = rqinfo
+ end
+ set $done = 0
+ printf "\nTime\t\t\t Event\t\t Buf\tDev\t Offset\tBytes\tSD\tSDoff\tDoffset\tGoffset\n\n"
+ while ($done == 0)
+ if ($rqip->bp != 0)
+ printf "%d.%06d\t", $rqip->timestamp.tv_sec, $rqip->timestamp.tv_usec
+ if ($rqip->type == loginfo_user_bp)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "1VS Read"
+ else
+ printf "1VS Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount
+ end
+
+ if ($rqip->type == loginfo_user_bpl)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "2LR Read"
+ else
+ printf "2LR Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount
+ end
+
+ if ($rqip->type == loginfo_rqe)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "3RQ Read"
+ else
+ printf "3RQ Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset
+ end
+
+ if ($rqip->type == loginfo_iodone)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "4DN Read"
+ else
+ printf "4DN Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset
+ end
+
+ if ($rqip->type == loginfo_raid5_data)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "5RD Read"
+ else
+ printf "5RD Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset
+ end
+
+ if ($rqip->type == loginfo_raid5_parity)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "6RP Read"
+ else
+ printf "6RP Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset
+ end
+
+ if ($rqip->type == loginfo_sdio)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "7VS Read"
+ else
+ printf "7VS Write"
+ end
+ printf "\t%p\t\t 0x%-9x\t%ld\t%d\n", $rqip->bp, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount, $rqip->devminor & 0xff
+ end
+
+ if ($rqip->type == loginfo_sdiol)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "8LR Read"
+ else
+ printf "8LR Write"
+ end
+ printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount
+ end
+
+ if ($rqip->type == loginfo_lockwait)
+ printf "Lockwait %p\t%d\t 0x%x\n", $rqip->bp, $rqip->info.lockinfo.plexno, $rqip->info.lockinfo.stripe
+ end
+
+ if ($rqip->type == loginfo_lock)
+ printf "Lock \t%p\t%d\t 0x%x\n", $rqip->bp, $rqip->info.lockinfo.plexno, $rqip->info.lockinfo.stripe
+ end
+
+ if ($rqip->type == loginfo_unlock)
+ printf "Unlock \t%p\t%d\t 0x%x\n", $rqip->bp, $rqip->info.lockinfo.plexno, $rqip->info.lockinfo.stripe
+ end
+
+ if ($rqip->type == loginfo_sdiodone)
+ if ($rqip->info.b.b_flags & 0x00100000)
+ printf "9DN Read"
+ else
+ printf "9DN Write"
+ end
+ printf "\t%p\t\t 0x%-9x\t%ld\t%d\n", $rqip->bp, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount, $rqip->devminor
+ end
+
+ end
+ set $rqip = $rqip + 1
+ if ($rqip == $rqipe)
+ set $done = 1
+ end
+ if ($rqip == $rqend)
+ set $rqip = rqinfo
+ end
+ end
+end
+document rqinfo
+Show the Vinum request log buffer, like 'vinum info -V'
+end
+define meminfo
+y
+printf "Block\t\tTime\t\tSequence\t size\t address\t line\t\tfile\n"
+set $i = 0
+while $i < malloccount
+ printf "%6d\t%10d.%06d\t%6d\t\t%6d\t0x%08x\t%6d\t\t%s\n", $i, malloced [$i].time.tv_sec, malloced [$i].time.tv_usec, malloced [$i].seq, malloced[$i].size, malloced[$i].address, malloced[$i].line, &malloced[$i].file
+ set $i = $i + 1
+end
+end
+document meminfo
+Equivalent of 'vinum info -v' command
+end
+define finfo
+y
+printf "Block\t\tTime\t\tSequence\t size\t address\t line\t\tfile\n"
+set $i = lastfree
+set $j = 0
+while $j < 64
+ if $i == 64
+ set $i = 0
+ end
+ if freeinfo[$i].line != 0
+ printf "%6d\t%10d.%06d\t%6d\t\t%6d\t0x%08x\t%6d\t\t%s\n", $i, freeinfo [$i].time.tv_sec, freeinfo [$i].time.tv_usec, freeinfo [$i].seq, freeinfo[$i].size, freeinfo[$i].address, freeinfo[$i].line, &freeinfo[$i].file
+ end
+ set $i = $i + 1
+ set $j = $j + 1
+end
+end
+document finfo
+Equivalent of 'vinum info -v' command
+end