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
|
# 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 [ $(egrep -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
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 egrep '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
VALGRIND_CMD="$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)
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
}
|