#!/bin/csh # # gdbmodules -- gdb wrapper adding symbol information from loaded modules # Darrell Anderson 1/99 with help from Drew (: # # usage: # if no arguments are given, run on the active kernel. # if one argument, use /var/crash/kernel.ARG, vmcore.ARG. # if two arguments, use them as kernel and core. # # also, a "--" argument terminates the script flags, anything following # is passed to the gdb command line flags. set VERBOSE = 0 set TMPFILE = /var/run/gdbmodstmp.$USER if (-e $TMPFILE) /bin/rm $TMPFILE touch $TMPFILE echo "please be patient while loaded modules are resolved" if ($#argv >= 2 && $1 != "--" && $2 != "--") then set KERNEL = $1 set CORE = $2 shift shift else if ($#argv >= 1 && $1 != "--") then set KERNEL = /var/crash/kernel.$1 set CORE = /var/crash/vmcore.$1 shift else if ($#argv == 0 || ($#argv > 0 && $1 == "--")) then set KERNEL = `sysctl kern.bootfile | awk '{print $2}'` set CORE = /dev/mem else echo "huh?" exit 1 endif echo "gdbmods using kernel: $KERNEL" echo "gdbmods using core: $CORE" if ($#argv > 0) then if ($1 != "--") then echo "something in the initial parsing is broken" exit 1 endif shift endif if ($VERBOSE) echo "gdb extra arguments: $argv" if (! -e $KERNEL) then echo "can't find file $KERNEL" exit 1 endif if (! -r $KERNEL) then echo "no read permission for $KERNEL" exit 1 endif if (! -e $CORE) then echo "can't find file $CORE" exit 1 endif if (! -r $CORE) then echo "no read permission for $CORE" exit 1 endif if (`uname -m` == alpha) then echo "target kcore $CORE" >> $TMPFILE set GDB_BINARY = "gdb" set GDB = "$GDB_BINARY -n -quiet -x $TMPFILE $KERNEL" else set GDB_BINARY = "gdb" set GDB = "$GDB_BINARY -k -n -quiet -x $TMPFILE $KERNEL $CORE" endif # # assume modules came from same build pool as kernel (bad assumption..) # perhaps consult an environment variable instead/as well? # if (!($?MODPATH)) then set MODPATH = `strings $KERNEL | grep 'sys/compile' | sed -e 's/.*://' | sed -e 's/compile.*/modules/'` set MODPATH = `echo "$MODPATH" | sed -e 's#\.amd_mnt#a#'` endif if ($MODPATH == "") then if ($VERBOSE) echo "must be using buildkernel.." set MODPATH = `strings $KERNEL | grep 'usr/obj/usr/src/sys' | sed -e 's/.*://'` endif if (! -d $MODPATH) then echo "bad module path $MODPATH" exit 1 endif if ($VERBOSE) echo "MODPATH $MODPATH" # # locate first module, skipping the "kernel" entry # set MODULE = `echo "print linker_files->tqh_first->link.tqe_next" | $GDB |& grep "linker_file" | awk '{print $7}'` if ($VERBOSE) echo "MODULE $MODULE" # # iterate over all modules # while ($MODULE != 0x0 && $MODULE != '') # # get the module name # set MODNAME = `echo "print ((struct linker_file *)$MODULE)->filename" | $GDB |& grep "gdb" | awk '{print $5}' | sed -e 's/\"//g'` ##HUH set MODNAME = `echo $MODNAME | sed -e "s@$TMPFILE@@g"` if ($VERBOSE) echo "MODNAME $MODNAME" # # get the module load address # set MODADDR = `echo "print ((struct linker_file *)$MODULE)->address" | $GDB |& grep "gdb" | awk '{print $4}'` ##HUH set MODADDR = `echo $MODADDR | sed -e 's/\-x//g'` if ($VERBOSE) echo "MODADDR $MODADDR" # # find the module file # can get default module path from `sysctl kern.module_path` XXX # prefer modules with the archtype in the path. # set ARCH = `uname -m` set MODFILE = `find $MODPATH -name "$MODNAME" -print | grep $ARCH` if ($MODFILE == "") then set MODFILE = `find $MODPATH -name "$MODNAME" -print` if ($MODFILE == "") then set MODFILE = `find /modules -name "$MODNAME" -print` endif endif if ($MODFILE == "") then echo "can't find module $MODNAME" else if ($VERBOSE) echo "MODFILE $MODFILE" # # find the text segment offset # set MODOFFS = `objdump --headers $MODFILE | grep ".text" | grep -v ".rel.text" | awk '{print $6}'` set MODOFFS = `echo 0x${MODOFFS}` if ($VERBOSE) echo "MODOFFS $MODOFFS" # # add the load command to the command file # echo "add-symbol-file $MODFILE $MODADDR + $MODOFFS" >> $TMPFILE # # report status # echo "added symbols for module $MODNAME" endif # # locate next module # set MODULE = \ `echo "print ((struct linker_file *)$MODULE)->link.tqe_next" | $GDB |& grep "linker_file" | awk '{print $7}'` if ($VERBOSE) echo "MODULE $MODULE" end # # for some reason adding symbols confuses the frame information. kludge. # echo "select-frame 0" >> $TMPFILE # # invoke the real gdb with the command file # if (`uname -m` == alpha) then if ($VERBOSE) echo "command line: $GDB_BINARY -x $TMPFILE $argv $KERNEL" $GDB_BINARY -x $TMPFILE $argv $KERNEL else if ($VERBOSE) echo "command line: $GDB_BINARY -k -x $TMPFILE $argv $KERNEL $CORE" $GDB_BINARY -k -x $TMPFILE $argv $KERNEL $CORE endif /bin/rm $TMPFILE #EOF#