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