1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
# Copyright (C) 2013, 2015 Red Hat, Inc.
# This file is part of elfutils.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# elfutils is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. $srcdir/test-subr.sh
# Verify one of the backtraced threads contains function 'main'.
check_main()
{
if grep -w main $1; then
return
fi
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()
{
if ! grep -w gsignal $1; then
return
fi
echo >&2 $2: found gsignal
false
}
# Makes sure we saw the function that initiated the backtrace
# when the core was generated through the tests backtrace --gencore.
# This might disappear when frame pointer chasing gone bad.
check_backtracegen()
{
if grep -w backtracegen $1; then
return
fi
echo >&2 $2: no backtracegen
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 [ $(grep -E -v <$1 'dwfl_thread_getframes: (No DWARF information found|no matching address range|address out of range|Invalid register|\(null\))$' \
| wc -c) \
-eq 0 ]
then
return
fi
echo >&2 $2: neither empty nor just out of DWARF
false
}
check_all()
{
bt=$1
err=$2
testname=$3
check_main $bt $testname
check_gsignal $bt $testname
check_err $err $testname
}
check_unsupported()
{
err=$1
testname=$2
if grep -q ': Unwinding not supported for this architecture$' $err; then
echo >&2 $testname: arch not supported
test_cleanup
exit 77
fi
}
check_native_unsupported()
{
err=$1
testname=$2
check_unsupported $err $testname
# ARM is special. It is supported, but it doesn't use .eh_frame by default
# making the native tests fail unless debuginfo (for glibc) is installed
# and we can fall back on .debug_frame for the CFI.
case "`uname -m`" in
arm* )
if grep -E 'dwfl_thread_getframes(.*)No DWARF information found' $err; then
echo >&2 $testname: arm needs debuginfo installed for all libraries
exit 77
fi
;;
esac
}
check_core()
{
arch=$1
testfiles backtrace.$arch.{exec,core}
tempfiles backtrace.$arch.{bt,err}
echo ./backtrace ./backtrace.$arch.{exec,core}
testrun ${abs_builddir}/backtrace -e ./backtrace.$arch.exec --core=./backtrace.$arch.core 1>backtrace.$arch.bt 2>backtrace.$arch.err || true
cat backtrace.$arch.{bt,err}
check_unsupported backtrace.$arch.err backtrace.$arch.core
check_all backtrace.$arch.{bt,err} backtrace.$arch.core
check_backtracegen backtrace.$arch.bt backtrace.$arch.core
}
# Backtrace live process.
# Do not abort on non-zero exit code due to some warnings of ./backtrace
# - see function check_err.
check_native()
{
child=$1
tempfiles $child.{bt,err}
(set +ex; testrun ${abs_builddir}/backtrace --backtrace-exec=${abs_builddir}/$child 1>$child.bt 2>$child.err; true)
cat $child.{bt,err}
check_native_unsupported $child.err $child
check_all $child.{bt,err} $child
}
# Backtrace core file.
check_native_core()
{
# systemd-coredump/coredumpctl doesn't seem to like concurrent core dumps
# use a lock file (fd 200) tests/core-dump-backtrace.lock
(
child=$1
# Disable valgrind while dumping core.
SAVED_VALGRIND_CMD="$VALGRIND_CMD"
unset VALGRIND_CMD
# Wait for lock for 10 seconds or skip.
flock -x -w 10 200 || exit 77;
# Skip the test if we cannot adjust core ulimit.
pid="`ulimit -c unlimited || exit 77; set +ex; testrun ${abs_builddir}/$child --gencore; true`"
core="core.$pid"
# see if /proc/sys/kernel/core_uses_pid is set to 0
if [ -f core ]; then
mv core "$core"
fi
type -P coredumpctl && have_coredumpctl=1 || have_coredumpctl=0
if [ ! -f "$core" -a $have_coredumpctl -eq 1 ]; then
# Maybe systemd-coredump took it. But give it some time to dump first...
sleep 1
coredumpctl --output="$core" dump $pid || rm -f $core
# Try a couple of times after waiting some more if something went wrong...
if [ ! -f "$core" ]; then
sleep 2
coredumpctl --output="$core" dump $pid || rm -f $core
fi
if [ ! -f "$core" ]; then
sleep 3
coredumpctl --output="$core" dump $pid || rm -f $core
fi
fi
if [ ! -f "$core" ]; then
# In some containers our view of pids is confused. Since tests are
# run in a new fresh directory any core here is most like is ours.
if ls core.[0-9]* 1> /dev/null 2>&1; then
mv core.[0-9]* "$core"
fi
fi
if [ ! -f "$core" ]; then
echo "No $core file generated";
exit 77;
fi
if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
# Restore $VALGRIND_CMD but disable --track-fds for the following testrun.
# Valgrind --track-fds might complain about an inherited fd.
VALGRIND_CMD=$(sed 's/--track-fds=yes//g' <<< "$SAVED_VALGRIND_CMD")
export VALGRIND_CMD
fi
# 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 -e ${abs_builddir}/$child --core=$core 1>$core.bt 2>$core.err; true)
if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
VALGRIND_CMD="$SAVED_VALGRIND_CMD"
export VALGRIND_CMD
fi
cat $core.{bt,err}
check_native_unsupported $core.err $child-$core
check_all $core.{bt,err} $child-$core
rm $core{,.{bt,err}}
) 200>${abs_builddir}/core-dump-backtrace.lock
}
|