1# Copyright (C) 2002-2020 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 16 17# test debuginfod with readelf and objdump 18 19set test "debuginfod" 20 21if {[which debuginfod] == 0} { 22 unsupported "$test (not found)" 23 return 24} 25 26if {[which curl] == 0} { 27 unsupported "$test (curl not found)" 28 return 29} 30 31if { ![is_elf_format] } { 32 unsupported "$test (unsupported target)" 33} 34 35if { [which $OBJDUMP] == 0} { 36 perror "$test $OBJDUMP (does not exist)" 37 return 38} 39 40 if { [which $READELF] == 0} { 41 perror "$test $READELF (does not exist)" 42 return 43} 44 45# Compile testprog.c, move the debuginfo to a separate file and add .gnu_debuglink. 46if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog executable debug] != ""} { 47 fail "$test (compilation failed)" 48 return 49} 50 51if { [binutils_run $OBJCOPY "--only-keep-debug tmpdir/testprog tmpdir/testprog.debug"] != "" } { 52 fail "$test (create separate debug info file)" 53 return 54} 55 56if { [binutils_run $OBJCOPY "--strip-debug tmpdir/testprog"] != "" } { 57 fail "$test (strip debug info)" 58 return 59} 60 61if { [binutils_run $OBJCOPY "--add-gnu-debuglink=tmpdir/testprog.debug tmpdir/testprog"] != "" } { 62 fail "$test (add debuglink)" 63 return 64} 65 66# Assemble an elf file with a debugaltlink 67if { ![binutils_assemble $srcdir/$subdir/debuglink.s tmpdir/debuglink.o] } { 68 fail "$test (assemble debuglink)" 69} 70 71if { ![binutils_assemble $srcdir/$subdir/linkdebug.s tmpdir/linkdebug.debug] } { 72 fail "$test (assemble linkdebug)" 73} 74 75set cache [file join [pwd] "tmpdir/.debuginfod_cache"] 76set db [file join [pwd] "tmpdir/.debuginfod.db"] 77 78setenv DEBUGINFOD_URLS "" 79setenv DEBUGINFOD_TIMEOUT 30 80setenv DEBUGINFOD_CACHE_PATH $cache 81 82# Move debug files into another directory so that readelf and objdump cannot 83# find them without debuginfod. 84file mkdir tmpdir/dbg 85file rename -force tmpdir/testprog.debug tmpdir/dbg 86file rename -force tmpdir/linkdebug.debug tmpdir/dbg 87 88# Remove old cache and database if they exist. 89file delete -force $cache 90file delete -force $db 91 92# Check whether objdump and readelf are configured with debuginfod. 93# To check this we attempt to follow a broken debuglink. If configured 94# with debuginfod the output will contain the debuginfod URLs that were 95# queried (these queries fail since the server is not yet running). 96set conf_objdump [binutils_run $OBJDUMP "-WK tmpdir/testprog"] 97set conf_readelf [binutils_run $READELF "-wK tmpdir/testprog"] 98 99# Find an unused port 100set port 7999 101set found 0 102while { ! $found } { 103 incr port 104 if { $port == 65536 } { 105 untested "$test (no available ports)" 106 return 107 } 108 109 spawn debuginfod -vvvv -d $db -p $port -F tmpdir/dbg 110 expect { 111 "started http server on IPv4 IPv6 port=$port" { 112 set found 1 113 } 114 "Failed to bind to port" { 115 exec kill -INT -[exp_pid] 116 catch {close}; catch {wait -i $spawn_id} 117 } 118 timeout { 119 fail "$test (find port timeout)" 120 return 121 } 122 } 123} 124 125set metrics [list "ready 1" \ 126 "thread_work_total{role=\"traverse\"} 1" \ 127 "thread_work_pending{role=\"scan\"} 0" \ 128 "thread_busy{role=\"scan\"} 0"] 129 130# Check server metrics to confirm init has completed. 131foreach m $metrics { 132 set timelim 20 133 while { $timelim != 0 } { 134 sleep 0.5 135 136 catch {exec curl -s http://127.0.0.1:$port/metrics} got 137 138 if { [regexp $m $got] } { 139 break 140 } 141 142 incr timelim -1 143 } 144 145 if { $timelim == 0 } { 146 fail "$test (server init timeout)" 147 exec kill -INT -[exp_pid] 148 catch {close}; catch {wait -i $spawn_id} 149 return 150 } 151} 152 153setenv DEBUGINFOD_URLS http://127.0.0.1:$port 154 155# Test whether prog can fetch separate debuginfo using debuginfod 156# if it's configured to do so. 157proc test_fetch_debuglink { prog progargs } { 158 global test 159 global cache 160 161 set got [binutils_run $prog "$progargs tmpdir/testprog"] 162 163 if { [regexp ".*Found separate debug info file.*Contents\[^\n\]*loaded from\[^\n\]*$cache.*" $got] } { 164 pass "$test ($prog debuglink)" 165 } else { 166 fail "$test ($prog debuglink)" 167 } 168} 169 170# Test whether prog can fetch debugaltlink files using debuginfod 171# if it's configured to do so. 172proc test_fetch_debugaltlink { prog progargs } { 173 global test 174 global cache 175 176 set got [binutils_run $prog "$progargs tmpdir/debuglink.o"] 177 set buildid "00112233445566778899aabbccddeeff0123456789abcdef" 178 179 if { [regexp ".*Found separate debug info file\[^\n\]*$cache/$buildid" $got] } { 180 pass "$test ($prog debugaltlink)" 181 } else { 182 fail "$test ($prog debugaltlink)" 183 } 184} 185 186if { [regexp ".*DEBUGINFOD.*" $conf_objdump] } { 187 test_fetch_debuglink $OBJDUMP "-W" 188 test_fetch_debugaltlink $OBJDUMP "-WK" 189} else { 190 untested "$test (objdump not configured with debuginfod)" 191} 192 193if { [regexp ".*DEBUGINFOD.*" $conf_readelf] } { 194 test_fetch_debuglink $READELF "-w" 195 test_fetch_debugaltlink $READELF "-wK" 196} else { 197 untested "$test (readelf not configured with debuginfod)" 198} 199