#!/bin/bash

function usage {
    cat <<EOF
Usage: $0 [--alt] [ --file output_file ] pid
EOF
    exit 1
}

# This doesn't work because stdout is redirected (by the backticks)
# before /dev/stdout is read.
#file=`readlink -f /dev/stdout`

# dup2(1, 10)
exec 10>&1
file=`readlink -f /dev/fd/10`
exec 10<&-

while [ $# -gt 0 ]; do
    case "$1" in
	--alt)
           alt=t
           shift
           ;;
	--file)
	   file=$2
	   shift 2
           ;;
	--bin)
	   binary=$2
	   shift 2
	   ;;
        -*)
           echo Invalid flag: $1
           usage
           ;;
        *)
           break
           ;;
    esac
done

if [ $# -ne 1 ]; then
	usage
fi

script=/tmp/lbt.$$.tmp

trap "rm -f $script" EXIT

cat <<EOF > $script
set unwindonsignal on
set lisp_print_level=2
bt
EOF

# In the current version of this program, $file is always
# non-empty, so this conditional could be removed.
if [ "$file" ]; then
cat <<EOF >> $script
call (int)dup(1)
set \$saved_stdout=\$
call (int)open("$file", 0101, 0666)
set \$filefd=\$
call (int)dup2(\$filefd,1)

EOF
fi

case `uname -m` in
    x86_64)  sp_reg='$rsp' ;;
    aarch64) sp_reg='$sp' ;;
    *)
        echo "$0: unsupported architecture: `uname -m`" >&2
        exit 1
        ;;
esac

if [ "$alt" ]; then
    cat <<EOF >> $script
call lisp_zo(acl_thread_control->registry[acl_thread_control->heap_owner]->c_leaf, 0)
EOF
else
    cat <<EOF >> $script
call lisp_zo($sp_reg,0)
EOF
fi

if [ "$file" ]; then
    cat <<EOF >>$script
call (int)close(\$filefd)
call (int)dup2(\$saved_stdout,1)
EOF
fi

if [ -f $file ]; then
    rm -f $file
fi
gdb $binary -p $1 -x $script --batch >> $file
