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