#!/bin/sh BASENAME=`basename $0` if [ -n "$VALGRIND" -o -n "$SMBD_VALGRIND" ]; then echo "${BASENAME}: Not running debugger under valgrind" exit 1 fi # we want everything on stderr, so the program is not disturbed exec 1>&2 BASENAME=`basename $0` UNAME=`uname` PID=$1 BINARY=$2 test x"${PID}" = x"" && { echo "Usage: ${BASENAME} <pid> [<binary>]" exit 1 } DB_LIST="gdb" case "${UNAME}" in # # on Tru64 we need to try ladebug first # because gdb crashes itself... # OSF1) DB_LIST="ladebug ${DB_LIST}" ;; # # On solaris dbx is working way more better than gdb # let's try it first # SunOS) DB_LIST="dbx ${DB_LIST}" ;; # # FreeBSD comes with a flavor that works gdb66 and one that don't gdb # (gdb 6.1) let's try it first the one that works ! # FreeBSD) DB_LIST="gdb66 ${DB_LIST}" ;; esac for DB in ${DB_LIST}; do DB_BIN=`which ${DB} 2>/dev/null | grep '^/'` test x"${DB_BIN}" != x"" && { break } done test x"${DB_BIN}" = x"" && { echo "${BASENAME}: ERROR: No debugger found." exit 1 } need_binary="no" case "${DB}" in # These debuggers need the process binary specified: ladebug) need_binary="yes" ;; gdb66) need_binary="yes" ;; dbx) need_binary="yes" ;; esac test x"${need_binary}" = x"yes" && { # we first try to use /proc/${PID}/exe or /proc/{$PID}/path for solaris # then fallback to the binary from the commandline # then we search for the commandline argument with # 'which' # test -f "/proc/${PID}/exe" && BINARY="/proc/${PID}/exe" test -f "/proc/${PID}/path/a.out" && BINARY=`ls -l /proc/${PID}/path/a.out |sed 's/.*-> //'` test x"${BINARY}" = x"" && BINARY="/proc/${PID}/exe" test -f "${BINARY}" || BINARY=`which ${BINARY}` test -f "${BINARY}" || { echo "${BASENAME}: ERROR: Cannot find binary '${BINARY}'." exit 1 } } BATCHFILE_PRE=/tmp/gdb_backtrace_pre.$$ BATCHFILE_MAIN=/tmp/gdb_backtrace_main.$$ case "${DB}" in ladebug) cat << EOF > ${BATCHFILE_PRE} set \$stoponattach EOF cat << EOF > ${BATCHFILE_MAIN} where quit EOF ${DB_BIN} -c "${BATCHFILE_MAIN}" -i "${BATCHFILE_PRE}" -pid "${PID}" "${BINARY}" ;; gdb66) cat << EOF > ${BATCHFILE_MAIN} set height 1000 bt full info locals kill quit EOF ${DB_BIN} -x "${BATCHFILE_MAIN}" "${BINARY}" "${PID}" ;; gdb) cat << EOF > ${BATCHFILE_MAIN} set height 0 bt full thread apply all bt full info locals quit EOF ${DB_BIN} -batch -x "${BATCHFILE_MAIN}" --pid "${PID}" < /dev/null ;; dbx) ${DB_BIN} "where;dump;kill;quit" "${BINARY}" "${PID}" ;; esac /bin/rm -f ${BATCHFILE_PRE} ${BATCHFILE_MAIN}