1# Copyright 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, see <http://www.gnu.org/licenses/>. 15 16# Test debuginfod functionality 17 18standard_testfile main.c 19 20load_lib dwarf.exp 21 22if { [which debuginfod] == 0 } { 23 untested "cannot find debuginfod" 24 return -1 25} 26 27if { [which curl] == 0 } { 28 untested "cannot find curl" 29 return -1 30} 31 32# Skip testing if gdb was not configured with debuginfod 33if { [string first "with-debuginfod" \ 34 [eval exec $GDB $INTERNAL_GDBFLAGS --configuration]] == -1 } { 35 untested "gdb not configured with debuginfod" 36 return -1 37} 38 39set cache [standard_output_file ".client_cache"] 40set db [standard_output_file ".debuginfod.db"] 41 42# Delete any preexisting test files 43file delete -force $cache 44file delete -force $db 45 46set sourcetmp [standard_output_file tmp-${srcfile}] 47set outputdir [standard_output_file {}] 48 49# Make a copy source file that we can move around 50if { [catch {file copy -force ${srcdir}/${subdir}/${srcfile} \ 51 [standard_output_file ${sourcetmp}]}] != 0 } { 52 error "create temporary file" 53 return -1 54} 55 56if { [gdb_compile "$sourcetmp" "$binfile" executable {debug}] != "" } { 57 fail "compile" 58 return -1 59} 60 61# Write some assembly that just has a .gnu_debugaltlink section. 62# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp. 63proc write_just_debugaltlink {filename dwzname buildid} { 64 set asm_file [standard_output_file $filename] 65 66 Dwarf::assemble $asm_file { 67 upvar dwzname dwzname 68 upvar buildid buildid 69 70 gnu_debugaltlink $dwzname $buildid 71 72 # Only the DWARF reader checks .gnu_debugaltlink, so make sure 73 # there is a bit of DWARF in here. 74 cu {} { 75 compile_unit {{language @DW_LANG_C}} { 76 } 77 } 78 } 79} 80 81# Write some DWARF that also sets the buildid. 82# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp. 83proc write_dwarf_file {filename buildid {value 99}} { 84 set asm_file [standard_output_file $filename] 85 86 Dwarf::assemble $asm_file { 87 declare_labels int_label int_label2 88 89 upvar buildid buildid 90 upvar value value 91 92 build_id $buildid 93 94 cu {} { 95 compile_unit {{language @DW_LANG_C}} { 96 int_label2: base_type { 97 {name int} 98 {byte_size 4 sdata} 99 {encoding @DW_ATE_signed} 100 } 101 102 constant { 103 {name the_int} 104 {type :$int_label2} 105 {const_value $value data1} 106 } 107 } 108 } 109 } 110} 111 112proc no_url { } { 113 global binfile outputdir debugdir 114 115 setenv DEBUGINFOD_URLS "" 116 117 # Test that gdb cannot find source without debuginfod 118 clean_restart $binfile 119 gdb_test_no_output "set substitute-path $outputdir /dev/null" \ 120 "set substitute-path" 121 gdb_test "list" ".*No such file or directory.*" 122 123 # Strip symbols into separate file and move it so gdb cannot find it \ 124 without debuginfod 125 if { [gdb_gnu_strip_debug $binfile ""] != 0 } { 126 fail "strip debuginfo" 127 return -1 128 } 129 130 set debugdir [standard_output_file "debug"] 131 set debuginfo [standard_output_file "fetch_src_and_symbols.debug"] 132 133 file mkdir $debugdir 134 file rename -force $debuginfo $debugdir 135 136 # Test that gdb cannot find symbols without debuginfod 137 clean_restart $binfile 138 gdb_test "file" ".*No symbol file.*" 139 140 set buildid "01234567890abcdef0123456" 141 142 write_just_debugaltlink ${binfile}_has_altlink.S ${binfile}_dwz.o \ 143 $buildid 144 write_dwarf_file ${binfile}_dwz.S $buildid 145 146 if {[gdb_compile ${binfile}_has_altlink.S ${binfile}_alt.o object \ 147 nodebug] != ""} { 148 fail "compile main with altlink" 149 return -1 150 } 151 152 if {[gdb_compile ${binfile}_dwz.S ${binfile}_dwz.o object \ 153 nodebug] != ""} { 154 fail "compile altlink" 155 return -1 156 } 157 158 file rename -force ${binfile}_dwz.o $debugdir 159 160 # Test that gdb cannot find dwz without debuginfod. 161 clean_restart 162 gdb_test "file ${binfile}_alt.o" \ 163 ".*could not find '.gnu_debugaltlink'.*" \ 164 "file [file tail ${binfile}_alt.o]" 165} 166 167proc local_url { } { 168 global binfile outputdir db debugdir 169 170 # Find an unused port 171 set port 7999 172 set found 0 173 while { ! $found } { 174 incr port 175 if { $port == 65536 } { 176 fail "no available ports" 177 return -1 178 } 179 180 spawn debuginfod -vvvv -d $db -p $port -F $debugdir 181 expect { 182 "started http server on IPv4 IPv6 port=$port" { set found 1 } 183 "failed to bind to port" { kill_wait_spawned_process $spawn_id } 184 timeout { 185 fail "find port timeout" 186 return -1 187 } 188 } 189 } 190 191 set metrics [list "ready 1" \ 192 "thread_work_total{role=\"traverse\"} 1" \ 193 "thread_work_pending{role=\"scan\"} 0" \ 194 "thread_busy{role=\"scan\"} 0"] 195 196 # Check server metrics to confirm init has completed. 197 foreach m $metrics { 198 set timelim 20 199 while { $timelim != 0 } { 200 sleep 0.5 201 catch {exec curl -s http://127.0.0.1:$port/metrics} got 202 203 if { [regexp $m $got] } { 204 break 205 } 206 207 incr timelim -1 208 } 209 210 if { $timelim == 0 } { 211 fail "server init timeout" 212 return -1 213 } 214 } 215 216 # Point the client to the server 217 setenv DEBUGINFOD_URLS http://127.0.0.1:$port 218 219 # gdb should now find the symbol and source files 220 clean_restart $binfile 221 gdb_test_no_output "set substitute-path $outputdir /dev/null" \ 222 "set substitute-path" 223 gdb_test "br main" "Breakpoint 1 at.*file.*" 224 gdb_test "l" ".*This program is distributed in the hope.*" 225 226 # gdb should now find the debugaltlink file 227 clean_restart 228 gdb_test "file ${binfile}_alt.o" \ 229 ".*Reading symbols from ${binfile}_alt.o\.\.\.*" \ 230 "file [file tail ${binfile}_alt.o]" 231} 232 233set envlist \ 234 [list \ 235 env(DEBUGINFOD_URLS) \ 236 env(DEBUGINFOD_TIMEOUT) \ 237 env(DEBUGINFOD_CACHE_PATH)] 238 239save_vars $envlist { 240 setenv DEBUGINFOD_TIMEOUT 30 241 setenv DEBUGINFOD_CACHE_PATH $cache 242 243 with_test_prefix no_url no_url 244 245 with_test_prefix local_url local_url 246} 247