#!/bin/sh # # print traceback of running python process # usage () { # rc local rc=$1 echo "$(basename "$0") " exit "$rc" } case "$1" in -h|--help) usage 0 ;; [1-9]*) PYPID="$1" ;; *) usage 2 >&2 ;; esac exe=$(readlink "/proc/$PYPID/exe") || usage 2 >&2 case "$exe" in /usr/bin/python2.?) ;; *) echo "Not a python process." >&2 exit 1 ;; esac dbg=/usr/lib/debug$exe ver=$(basename "$exe") if ! [ -f "$dbg" ] then echo "Missing Python debug symbols from package $ver-dbg" >&2 exit 1 fi tmpfile=$(mktemp) trap "rm -f '$tmpfile'" EXIT top="$(objdump -t "$dbg" | sed -ne 's!^[[:xdigit:]]\+[[:space:]].*[[:space:]]0*\([[:xdigit:]]\+\)[[:space:]]\(Py_Main\|t_bootstrap\)!($pc < \2 || $pc >= \2+0x\1) \\\&\\\& !p' | tr -d '\n')(0 < 1)" gdb=/usr/share/doc/$ver/gdbinit if [ -f "$gdb" ] then sed -e 's!\$pc < Py_Main || \$pc > Py_[[:graph:]]\+!'"$top"'!' "$gdb" >"$tmpfile" elif [ -f "$gdb.gz" ] then gzip -dc <"$gdb.gz" | sed -e 's!\$pc < Py_Main || \$pc > Py_[[:graph:]]\+!'"$top"'!' >"$tmpfile" else echo "Missing gdb file: $gdb" >&2 exit 1 fi gdb -p "$PYPID" -batch -n -x "$tmpfile" -ex "set pagination off" -ex "thread apply all pystack"