#!/bin/bash # # character is used for indentation # LC_ALL=C export LC_ALL usage (){ echo -n "\ This program analyses run-yamd's output and converts function addresses to source code position. Set YAMD_LIBDYN environment variable to libyamd-dynamic.so The default is /usr/local/lib/libyamd-dynamic.so usage: do-syms [OPTIONS] OPTIONS: --help displays this screen --with-gdb use 'gdb'. By default 'addr2line' is used. " } if test -z $YAMD_LIBDYN; then YAMD_LIBDYN=/usr/local/lib/libyamd-dynamic.so fi #export YAMD_LIBDYN while [ $# -ne 0 ]; do case $1 in --help) usage exit 0;; --with-gdb) with_gdb=1 shift;; --*) echo "unexpected option $1" exit 1;; *) break;; esac done if test $# -lt 1; then echo "Run do-syms --help for help" exit 1 fi exefile="$1" shift #trap 'rm -f $tmp_file $tmp_file1 $tmp_file2' 0 1 2 3 15 tmp_file=`mktemp /tmp/do-syms.XXXXXX` test $? || exit 1 tmp_file1=`mktemp /tmp/do-syms.XXXXXX` test $? || exit 2 tmp_file2=`mktemp /tmp/do-syms.XXXXXX` test $? || exit 3 cat "$@" > "$tmp_file" echo "$tmp_file1:$tmp_file2:$tmp_file with_gdb=$with_gdb" 1>&2 gawk --posix ' /\[0x[0-9a-fA-F]+\]/ { match($0, /\[0x[0-9a-fA-F]+\]/) print substr($0, RSTART + 1, RLENGTH - 2) }' "$tmp_file" | sort | uniq > "$tmp_file1" if test "_$with_gdb" = "_1"; then { echo 'set width 0' echo 'break _init' echo 'set print demangle on' echo "set environment LD_PRELOAD=$YAMD_LIBDYN" echo 'r' echo 'p/x 0x22552255' sed 's/^/b */' < "$tmp_file1" } | gdb -nx -q -batch -x /dev/stdin "$exefile" | #tee /dev/stderr | awk ' flag == 1 { for (i=1; i <= NF; ++i){ if ($i == "file"){ gsub(/[,.]$/, "", $(i+1)) printf "%s:", $(i+1) } if ($i == "line"){ gsub(/[,.]$/, "", $(i+1)) printf "%s ", $(i+1) } } printf "\n" } /22552255/ { flag=1 next }' # echo ${PIPESTATUS[@]} 1>&2 else xargs addr2line -e "$exefile" < "$tmp_file1" fi > $tmp_file2 awk -v tmp1=$tmp_file1 -v tmp2=$tmp_file2 ' BEGIN { while (0 < getline addr < tmp1 && 0 < getline src < tmp2){ h [addr] = src # print addr, h [addr] } } { match($0, /\[0x[0-9a-fA-F]+\]/) if (RSTART > 0){ addr = substr($0, RSTART + 1, RLENGTH - 2) print substr($0, 1, RSTART - 1), h [addr] }else{ print $0 } }' < "$tmp_file"