Hi Mark, as you requested I have commented more the tests/ part.
It is in: jankratochvil/unwindx86 Thanks, Jan
diff --git a/tests/backtrace.c b/tests/backtrace.c index e50399b..36995bc 100644 --- a/tests/backtrace.c +++ b/tests/backtrace.c @@ -162,7 +162,7 @@ frame_callback (Dwfl_Frame *state, void *frame_arg) if (! dwfl_frame_pc (state, &pc, &isactivation)) { error (0, 0, "%s", dwfl_errmsg (-1)); - return 1; + return DWARF_CB_ABORT; } Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); @@ -204,8 +204,8 @@ thread_callback (Dwfl_Thread *thread, void *thread_arg) { case 0: break; - case 1: - return 1; + case DWARF_CB_ABORT: + return DWARF_CB_ABORT; case -1: error (0, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1)); /* All platforms do not have yet proper unwind termination. */ @@ -232,17 +232,17 @@ dump (pid_t pid, const char *corefile, callback_t *callback, struct thread_callback thread_callback_data; thread_callback_data.callback = callback; thread_callback_data.callback_data = callback_data; - int err = 0; + bool err = false; switch (dwfl_getthreads (dwfl, thread_callback, &thread_callback_data)) { case 0: break; - case 1: - err = 1; + case DWARF_CB_ABORT: + err = true; break; case -1: error (0, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1)); - err = 1; + err = true; break; default: abort (); diff --git a/tests/run-backtrace.sh b/tests/run-backtrace.sh index 3f77da3..8e02403 100755 --- a/tests/run-backtrace.sh +++ b/tests/run-backtrace.sh @@ -17,32 +17,23 @@ . $srcdir/test-subr.sh -if [ -z "$VERBOSE" ]; then - exec >/dev/null -else - set -x -fi - -mytestrun() -{ - echo "$*" - testrun "$@" -} - +# Verify one of the backtraced threads contains function 'main'. check_main() { if grep -w main $1; then return fi - cat >&2 $1 $3 echo >&2 $2: no main false } +# Without proper ELF symbols resolution we could get inappropriate weak +# symbol "gsignal" with the same address as the correct symbol "raise". +# It was fixed by GIT commit 78dec228b3cfb2f9300cd0b682ebf416c9674c91 . +# [patch] Improve ELF symbols preference (global > weak) +# https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/002624.html check_gsignal() { - # Without proper ELF symbols resolution we could get inappropriate weak - # symbol "gsignal" with the same address as the correct symbol "raise". if ! grep -w gsignal $1; then return fi @@ -51,12 +42,15 @@ check_gsignal() false } +# Verify the STDERR output does not contain unexpected errors. +# In some cases we cannot reliably find out we got behind _start as some +# operating system do not properly terminate CFI by undefined PC. +# Ignore it here as it is a bug of OS, not a bug of elfutils. check_err() { if test ! -s $1; then return fi - # In some cases we cannot reliably find out we got behind _start. if cmp -s <(echo "${abs_builddir}/backtrace: dwfl_thread_getframes: no matching address range") <(uniq <$1); then return fi @@ -65,19 +59,36 @@ check_err() false } +check_all() +{ + bt=$1 + err=$2 + testname=$3 + cat $bt $err + check_main $bt $testname + check_gsignal $bt $testname + check_err $err $testname +} + +# Test both 64-bit and 32-bit tracees. Both files will be the same if the +# current platform does not support different target archs. for child in backtrace-child{,-biarch}; do - tempfiles $child{.bt,.err} + + # Backtrace live process. + # Do not abort on non-zero exit code due to some warnings of ./backtrace + # - see function check_err. + tempfiles $child.{bt,err} (set +ex; testrun ${abs_builddir}/backtrace ${abs_builddir}/$child 1>$child.bt 2>$child.err; true) - check_main $child.bt $child $child.err - check_gsignal $child.bt $child - check_err $child.err $child + check_all $child.{bt,err} $child + + # Backtrace core file. core="core.`ulimit -c unlimited; set +ex; testrun ${abs_builddir}/$child --gencore --run; true`" - tempfiles $core{,.bt,.err} + # Do not abort on non-zero exit code due to some warnings of ./backtrace + # - see function check_err. + tempfiles $core{,.{bt,err}} (set +ex; testrun ${abs_builddir}/backtrace ${abs_builddir}/$child $core 1>$core.bt 2>$core.err; true) - cat $core.{bt,err} - check_main $core.bt $child-$core $core.err - check_gsignal $core.bt $child-$core - check_err $core.err $child-$core + check_all $core.{bt,err} $child-$core + done exit 0