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
This commit is contained in:
parent
e4e7b5bc54
commit
173cc338ed
44
sys/debugscripts/.gdbinit
Normal file
44
sys/debugscripts/.gdbinit
Normal file
@ -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
|
386
sys/debugscripts/gdbinit.i386
Normal file
386
sys/debugscripts/gdbinit.i386
Normal file
@ -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
|
340
sys/debugscripts/gdbinit.kernel
Normal file
340
sys/debugscripts/gdbinit.kernel
Normal file
@ -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
|
334
sys/debugscripts/gdbinit.vinum
Normal file
334
sys/debugscripts/gdbinit.vinum
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user