1#!/bin/sh 2 3BASENAME=`basename $0` 4 5if [ -n "$VALGRIND" -o -n "$SMBD_VALGRIND" ]; then 6 echo "${BASENAME}: Not running debugger under valgrind" 7 exit 1 8fi 9 10# we want everything on stderr, so the program is not disturbed 11exec 1>&2 12 13BASENAME=`basename $0` 14UNAME=`uname` 15 16PID=$1 17BINARY=$2 18 19test x"${PID}" = x"" && { 20 echo "Usage: ${BASENAME} <pid> [<binary>]" 21 exit 1 22} 23 24DB_LIST="gdb" 25case "${UNAME}" in 26 # 27 # on Tru64 we need to try ladebug first 28 # because gdb crashes itself... 29 # 30 OSF1) 31 DB_LIST="ladebug ${DB_LIST}" 32 ;; 33 # 34 # On solaris dbx is working way more better than gdb 35 # let's try it first 36 # 37 SunOS) 38 DB_LIST="dbx ${DB_LIST}" 39 ;; 40 # 41 # FreeBSD comes with a flavor that works gdb66 and one that don't gdb 42 # (gdb 6.1) let's try it first the one that works ! 43 # 44 FreeBSD) 45 DB_LIST="gdb66 ${DB_LIST}" 46 ;; 47esac 48 49for DB in ${DB_LIST}; do 50 DB_BIN=`which ${DB} 2>/dev/null | grep '^/'` 51 test x"${DB_BIN}" != x"" && { 52 break 53 } 54done 55 56test x"${DB_BIN}" = x"" && { 57 echo "${BASENAME}: ERROR: No debugger found." 58 exit 1 59} 60 61need_binary="no" 62case "${DB}" in 63# These debuggers need the process binary specified: 64 ladebug) 65 need_binary="yes" 66 ;; 67 gdb66) 68 need_binary="yes" 69 ;; 70 dbx) 71 need_binary="yes" 72 ;; 73esac 74 75test x"${need_binary}" = x"yes" && { 76 77# we first try to use /proc/${PID}/exe or /proc/{$PID}/path for solaris 78# then fallback to the binary from the commandline 79# then we search for the commandline argument with 80# 'which' 81# 82 test -f "/proc/${PID}/exe" && BINARY="/proc/${PID}/exe" 83 test -f "/proc/${PID}/path/a.out" && BINARY=`ls -l /proc/${PID}/path/a.out |sed 's/.*-> //'` 84 test x"${BINARY}" = x"" && BINARY="/proc/${PID}/exe" 85 test -f "${BINARY}" || BINARY=`which ${BINARY}` 86 87 test -f "${BINARY}" || { 88 echo "${BASENAME}: ERROR: Cannot find binary '${BINARY}'." 89 exit 1 90 } 91} 92 93BATCHFILE_PRE=`mktemp --tmpdir gdb_backtrace_pre.XXXXXXXXXX` 94test -n "${BATCHFILE_PRE}" || { 95 echo "mktemp doesn't work" 1>&2 96 exit 1 97} 98BATCHFILE_MAIN=`mktemp --tmpdir gdb_backtrace_main.XXXXXXXXXX` 99test -n "${BATCHFILE_MAIN}" || { 100 echo "mktemp doesn't work" 1>&2 101 exit 1 102} 103case "${DB}" in 104 ladebug) 105cat << EOF > ${BATCHFILE_PRE} 106set \$stoponattach 107EOF 108 109cat << EOF > ${BATCHFILE_MAIN} 110where 111quit 112EOF 113 ${DB_BIN} -c "${BATCHFILE_MAIN}" -i "${BATCHFILE_PRE}" -pid "${PID}" "${BINARY}" 114 ;; 115 gdb66) 116cat << EOF > ${BATCHFILE_MAIN} 117set height 1000 118bt full 119info locals 120kill 121quit 122EOF 123 ${DB_BIN} -x "${BATCHFILE_MAIN}" "${BINARY}" "${PID}" 124 ;; 125 gdb) 126cat << EOF > ${BATCHFILE_MAIN} 127set height 0 128bt full 129thread apply all bt full 130info locals 131quit 132EOF 133 ${DB_BIN} -batch -x "${BATCHFILE_MAIN}" --pid "${PID}" < /dev/null 134 ;; 135dbx) 136 ${DB_BIN} "where;dump;kill;quit" "${BINARY}" "${PID}" 137 ;; 138esac 139/bin/rm -f ${BATCHFILE_PRE} ${BATCHFILE_MAIN} 140