#!/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