Commit | Line | Data |
---|---|---|
6a1939f5 NC |
1 | # Copyright (C) 2002-2019 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 | ||
19 | set test "debuginfod" | |
20 | ||
21 | if {[which debuginfod] == 0} { | |
22 | unsupported "$test (not found)" | |
23 | return | |
24 | } | |
25 | ||
26 | if {[which curl] == 0} { | |
27 | unsupported "$test (curl not found)" | |
28 | return | |
29 | } | |
30 | ||
31 | if { ![is_elf_format] } { | |
32 | unsupported "$test (unsupported target)" | |
33 | } | |
34 | ||
35 | if { [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. | |
46 | if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog executable debug] != ""} { | |
47 | fail "$test (compilation failed)" | |
48 | return | |
49 | } | |
50 | ||
51 | if { [binutils_run $OBJCOPY "--only-keep-debug tmpdir/testprog tmpdir/testprog.debug"] != "" } { | |
52 | fail "$test (create separate debug info file)" | |
53 | return | |
54 | } | |
55 | ||
56 | if { [binutils_run $OBJCOPY "--strip-debug tmpdir/testprog"] != "" } { | |
57 | fail "$test (strip debug info)" | |
58 | return | |
59 | } | |
60 | ||
61 | if { [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 | |
67 | if { ![binutils_assemble $srcdir/$subdir/debuglink.s tmpdir/debuglink.o] } { | |
68 | fail "$test (assemble debuglink)" | |
69 | } | |
70 | ||
71 | if { ![binutils_assemble $srcdir/$subdir/linkdebug.s tmpdir/linkdebug.debug] } { | |
72 | fail "$test (assemble linkdebug)" | |
73 | } | |
74 | ||
75 | # Find an unused port | |
76 | set port [exec sh -c "while true; do PORT=`expr '(' \$RANDOM % 1000 ')' + 9000`; ss -atn | fgrep \":\$PORT\" || break; done; echo \$PORT"] | |
77 | ||
6a1939f5 | 78 | set cache [file join [pwd] "tmpdir/.debuginfod_cache"] |
46471187 | 79 | set db [file join [pwd] "tmpdir/.debuginfod.db"] |
6a1939f5 | 80 | |
46471187 | 81 | setenv DEBUGINFOD_URLS "" |
678d457f AM |
82 | setenv DEBUGINFOD_TIMEOUT 30 |
83 | setenv DEBUGINFOD_CACHE_PATH $cache | |
6a1939f5 NC |
84 | |
85 | # Move debug files into another directory so that readelf and objdump cannot | |
86 | # find them without debuginfod. | |
87 | file mkdir tmpdir/dbg | |
88 | file rename -force tmpdir/testprog.debug tmpdir/dbg | |
89 | file rename -force tmpdir/linkdebug.debug tmpdir/dbg | |
90 | ||
46471187 | 91 | # Remove old cache and database if they exist. |
6a1939f5 | 92 | file delete -force $cache |
46471187 | 93 | file delete -force $db |
6a1939f5 NC |
94 | |
95 | # Check whether objdump and readelf are configured with debuginfod. | |
96 | # To check this we attempt to follow a broken debuglink. If configured | |
97 | # with debuginfod the output will contain the debuginfod URLs that were | |
98 | # queried (these queries fail since the server is not yet running). | |
99 | set conf_objdump [binutils_run $OBJDUMP "-WK tmpdir/testprog"] | |
100 | set conf_readelf [binutils_run $READELF "-wK tmpdir/testprog"] | |
101 | ||
102 | set debuginfod_pid 0 | |
103 | ||
104 | # Kill the server if we abort early | |
105 | proc sigint_handler {} { | |
106 | global debuginfod_pid | |
107 | ||
108 | if { $debuginfod_pid != 0 } { | |
109 | catch {exec kill -INT $debuginfod_pid} | |
110 | } | |
111 | ||
112 | exit | |
113 | } | |
114 | ||
115 | trap sigint_handler INT | |
116 | ||
117 | # Start a debuginfod server. | |
46471187 | 118 | set debuginfod_pid [exec debuginfod -d $db -p $port -F tmpdir/dbg 2>/dev/null &] |
6a1939f5 NC |
119 | |
120 | if { !$debuginfod_pid } { | |
121 | fail "$test (server init)" | |
122 | return | |
123 | } | |
124 | ||
46471187 AM |
125 | set 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 | "groom{statistic=\"buildids\"} 2"] | |
130 | ||
131 | # Check server metrics to confirm init has completed. | |
132 | foreach m $metrics { | |
133 | set timelim 20 | |
134 | while { $timelim != 0 } { | |
135 | sleep 0.5 | |
136 | ||
6a1939f5 NC |
137 | catch {exec curl -s http://127.0.0.1:$port/metrics} got |
138 | ||
46471187 | 139 | if { [regexp $m $got] } { |
6a1939f5 NC |
140 | break |
141 | } | |
6a1939f5 | 142 | |
46471187 AM |
143 | incr timelim -1 |
144 | } | |
145 | ||
146 | if { $timelim == 0 } { | |
147 | fail "$test (server init timeout)" | |
6a1939f5 NC |
148 | catch {exec kill -INT $debuginfod_pid} |
149 | return | |
46471187 | 150 | } |
6a1939f5 NC |
151 | } |
152 | ||
46471187 AM |
153 | setenv DEBUGINFOD_URLS http://127.0.0.1:$port |
154 | ||
6a1939f5 NC |
155 | # Test whether prog can fetch separate debuginfo using debuginfod |
156 | # if it's configured to do so. | |
157 | proc 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. | |
172 | proc 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 | ||
186 | if { [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 | ||
193 | if { [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 | ||
6a1939f5 | 200 | catch {exec kill -INT $debuginfod_pid} |