Web lists-archives.com

An increment to Jon Turney's stackdump2backtrace script




For those Cygwin developers who tend to attract stackdump files...

..mark (who defines an alias 'bt' to launch the script because he can't get gdb out of his head)

h/t to JT
#!/bin/bash
#
#	stackdump2backtrace (incremented)
#	Munges a Cygwin stackdump file into a real backtrace
#
#	Based on nifty stackdump2backtrace script by Jon Turney, as
#	posted in https://sourceware.org/ml/cygwin/2015-08/msg00311.html
#
#	2018/10/01 increment by Mark A. Geisert

# The user provides the name of the stackdump file
STACKDUMP=$1
if [ -z "$STACKDUMP" ]; then
    echo Usage: $0 name-of-stackdump-file
    exit 1
fi
if [ ! -e "$STACKDUMP" ]; then
    echo cannot find stackdump file $STACKDUMP
    exit 1
fi

# Look for executable's best available stashed debug info
IMG1=/usr/lib/debug/usr/bin/${STACKDUMP%.stackdump}.dbg

# If no stashed debug info available for executable, read from EXE
if [ ! -e "$IMG1" ]; then
    IMG1=${STACKDUMP%.stackdump}

    # If we can't find the EXE, try to locate it with 'which'
    if [ ! -e "$IMG1" ]; then
	IMG1=`basename $IMG1`
	IMG1=`which $IMG1`
    fi
fi

# If no luck locating executable image file, bail
if [ ! -e "$IMG1" ]; then
    echo cannot find executable file $IMG1
    exit 1
fi

# Look for Cygwin DLL's best available stashed debug info
IMG2=/usr/lib/debug/usr/bin/cygwin1.dbg
if [ ! -e "$IMG2" ]; then
    IMG2="" # not found; just use what ldd locates later on
fi

# Construct list of image files to resolve addresses against
# Sorting into reverse order seems to improve address lookup performance
OTHERS=`ldd $IMG1 | awk '{print $3}' | sort -r | tr '\\n' ' '`
IMAGES="$IMG1 $IMG2 $OTHERS"

display() {
    declare -g IMAGES

    # look up address $1 in each known image; break on first success
    for img in $IMAGES
    do
	line=`addr2line -asfiC -e $img $1`
	echo $line | fgrep -q "??:0"
	if [ $? -ne 0 ]; then
	    break
	fi
    done

    # state machine for prettier display of addr2line output
    addr=""
    temp=""
    for word in $line
    do
	case $word in
	0x*)
	    addr=$word
	    temp=""
	    ;;
	\?\?:0 | *.*:*)
	    echo "$addr | $word | $temp"
	    addr="     or maybe     "
	    temp=""
	    ;;
	*)
	    temp+="$word "
	    ;;
	esac
    done
}

# Read and process each stack frame line of the stackdump file
grep "^Exception:" $STACKDUMP
awk '/^[0-9A-F][0-9A-F]/ {print $2}' $STACKDUMP | while read ADDR
do
    display $ADDR
done | column -o' ' -t -s'|'

# Deal with register-dump form of stackdump file. No frames here.
COUNT=`grep -c "^[0-9A-F][0-9A-F]" $STACKDUMP`
if [ X"$COUNT" = X0 ]; then
    ADDR=`grep "^Exception:" $STACKDUMP | awk '{print $4}' | sed 's/rip=/0x/'`
    if [ X"$ADDR" != X ]; then
	display $ADDR | column -o' ' -t -s'|'
    fi
    echo no stack frames present
fi

# And that's all the misinfotainment we have time for
exit 0
--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple