Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2019-2020 Free Software Foundation, Inc. |
aa2d5a42 KS |
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 | # Based on break.exp, written by Rob Savoye. (rob@cygnus.com) | |
17 | # Modified to test gdb's handling of separate debug info files. | |
18 | # Modified to test gdb's handling of a debug-id retrieval. | |
19 | ||
20 | # Build-id-related tests for core files. | |
21 | ||
22 | standard_testfile | |
23 | ||
24 | # Build a non-shared executable. | |
25 | ||
26 | proc build_corefile_buildid_exec {} { | |
27 | global testfile srcfile binfile execdir | |
28 | ||
29 | if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { | |
30 | untested "failed to compile" | |
31 | return false | |
32 | } | |
33 | ||
34 | # Move executable to non-default path. | |
35 | set builddir [standard_output_file $execdir] | |
36 | remote_exec build "rm -rf $builddir" | |
37 | remote_exec build "mkdir $builddir" | |
38 | remote_exec build "mv $binfile [file join $builddir [file tail $binfile]]" | |
39 | ||
40 | return true | |
41 | } | |
42 | ||
43 | # Build a shared executable. | |
44 | ||
45 | proc build_corefile_buildid_shared {} { | |
46 | global srcdir subdir testfile binfile srcfile sharedir | |
47 | ||
48 | set builddir [standard_output_file $sharedir] | |
49 | ||
50 | # Compile DSO. | |
51 | set srcdso [file join $srcdir $subdir $testfile-shlib-shr.c] | |
52 | set objdso [standard_output_file $testfile-shlib-shr.so] | |
53 | if {[gdb_compile_shlib $srcdso $objdso {debug}] != ""} { | |
54 | untested "failed to compile dso" | |
55 | return false | |
56 | } | |
57 | ||
58 | # Compile shared library. | |
59 | set srclib [file join $srcdir $subdir $testfile-shlib.c] | |
60 | set libname lib$testfile.so | |
61 | set objlib [standard_output_file $libname] | |
62 | set dlopen_lib [shlib_target_file \ | |
63 | [file join $builddir [file tail $objdso]]] | |
64 | set opts [list debug shlib_load \ | |
65 | additional_flags=-DSHLIB_NAME=\"$dlopen_lib\"] | |
66 | if {[gdb_compile_shlib $srclib $objlib $opts] != ""} { | |
67 | untested "failed to compile shared library" | |
68 | return false | |
69 | } | |
70 | ||
71 | # Compile main program. | |
72 | set srcexec [file join $srcdir $subdir $srcfile] | |
73 | set binfile [standard_output_file $testfile-shared] | |
74 | set opts [list debug shlib=$objlib additional_flags=-DTEST_SHARED] | |
75 | if {[gdb_compile $srcexec $binfile executable $opts] != ""} { | |
76 | untested "failed to compile shared executable" | |
77 | return false | |
78 | } | |
79 | ||
80 | # Move objects to non-default path. | |
81 | remote_exec build "rm -rf $builddir" | |
82 | remote_exec build "mkdir $builddir" | |
83 | remote_exec build "mv $binfile $builddir" | |
84 | remote_exec build "mv $objdso $builddir" | |
85 | remote_exec build "mv $objlib $builddir" | |
86 | ||
87 | return true | |
88 | } | |
89 | ||
90 | # Append DEBUGDIR to the debug-file-directory path. | |
91 | ||
92 | proc append_debug_dir {debugdir} { | |
93 | global gdb_prompt | |
94 | ||
95 | set orig_debugdir {} | |
96 | gdb_test_multiple "show debug-file-directory" \ | |
97 | "get debug-file-directory" { | |
98 | -re "The directory where separate debug symbols are searched for is \"(.*)\"\.\[\r\n\]+$gdb_prompt $" { | |
99 | set orig_debugdir $expect_out(1,string) | |
100 | pass "get debug-file-directory" | |
101 | } | |
102 | } | |
103 | gdb_test_no_output "set debug-file-directory $debugdir:$orig_debugdir" \ | |
104 | "append debug directory" | |
105 | } | |
106 | ||
107 | # A convenience procedure to check if "info files" mentions the exec file | |
108 | # FILE. | |
109 | ||
110 | proc check_exec_file {file} { | |
623563f7 | 111 | global gdb_prompt |
aa2d5a42 | 112 | send_log "expecting exec file \"$file\"\n" |
623563f7 TV |
113 | |
114 | # Get line with "Local exec file:". | |
115 | set ok 0 | |
590003dc TV |
116 | gdb_test_multiple "info files" "" -lbl { |
117 | -re "\r\nLocal exec file:" { | |
623563f7 TV |
118 | set test_name $gdb_test_name |
119 | set ok 1 | |
120 | } | |
623563f7 TV |
121 | } |
122 | ||
123 | if { $ok == 0 } { | |
124 | return | |
125 | } | |
126 | ||
127 | # Get subsequent line with $file. | |
128 | set ok 0 | |
590003dc TV |
129 | gdb_test_multiple "" $test_name -lbl { |
130 | -re "\r\n\[\t\ \]+`[string_to_regexp $file]'\[^\r\n\]*" { | |
623563f7 TV |
131 | set ok 1 |
132 | } | |
623563f7 TV |
133 | } |
134 | ||
135 | if { $ok == 0 } { | |
136 | return | |
137 | } | |
138 | ||
139 | # Skip till prompt. | |
590003dc TV |
140 | gdb_test_multiple "" $test_name -lbl { |
141 | -re "\r\n$gdb_prompt $" { | |
623563f7 TV |
142 | pass $gdb_test_name |
143 | } | |
623563f7 | 144 | } |
aa2d5a42 KS |
145 | } |
146 | ||
147 | # Test whether gdb can find an exec file from a core file's build-id. | |
148 | # The executable (and separate debuginfo if SEPDEBUG is true) is | |
149 | # copied to the .build-id directory. | |
150 | # | |
151 | # SUFFIX is appended to the .builid-id parent directory name to | |
152 | # keep all tests separate. | |
153 | # SYMLINK specifies whether build-id files should be copied or symlinked. | |
154 | # SHARED is a boolean indicating whether we are testing the shared | |
155 | # library core dump test case. | |
156 | ||
157 | proc locate_exec_from_core_build_id {corefile buildid suffix \ | |
158 | sepdebug symlink shared} { | |
159 | global testfile binfile srcfile | |
160 | ||
161 | clean_restart | |
162 | ||
163 | # Set up the build-id directory and symlink the binary there. | |
164 | if {$symlink} { | |
165 | set d "symlinkdir" | |
166 | } else { | |
167 | set d "debugdir" | |
168 | } | |
169 | set debugdir [standard_output_file $d-$suffix] | |
170 | remote_exec build "rm -rf $debugdir" | |
171 | remote_exec build \ | |
172 | "mkdir -p [file join $debugdir [file dirname $buildid]]" | |
173 | ||
174 | set files_list {} | |
175 | if {$sepdebug} { | |
176 | lappend files_list "$binfile.stripped" $buildid | |
177 | lappend files_list "$binfile.debug" "$buildid.debug" | |
178 | } else { | |
179 | lappend files_list $binfile $buildid | |
180 | } | |
181 | if {$shared} { | |
182 | global sharedir | |
183 | set builddir [standard_output_file $sharedir] | |
184 | } else { | |
185 | global execdir | |
186 | set builddir [standard_output_file $execdir] | |
187 | } | |
188 | foreach {target name} $files_list { | |
189 | set t [file join $builddir [file tail $target]] | |
190 | if {$symlink} { | |
191 | remote_exec build "ln -s $t [file join $debugdir $name]" | |
192 | } else { | |
193 | remote_exec build "cp $t [file join $debugdir $name]" | |
194 | } | |
195 | } | |
196 | ||
197 | # Append the debugdir to the separate debug directory search path. | |
198 | append_debug_dir $debugdir | |
199 | ||
200 | gdb_test "core-file $corefile" "Program terminated with .*" \ | |
201 | "load core file" | |
202 | if {$symlink} { | |
203 | if {$sepdebug} { | |
204 | set expected_file [file join $builddir \ | |
205 | [file tail "$binfile.stripped"]] | |
206 | } else { | |
207 | set expected_file [file join $builddir [file tail $binfile]] | |
208 | } | |
209 | } else { | |
210 | set expected_file $buildid | |
211 | } | |
212 | check_exec_file [file join $debugdir $expected_file] | |
213 | } | |
214 | ||
215 | # Run a build-id tests on a core file. | |
216 | # Supported options: "-shared" and "-sepdebug" for running tests | |
217 | # of shared and/or stripped/.debug executables. | |
218 | ||
219 | proc do_corefile_buildid_tests {args} { | |
220 | global binfile testfile srcfile execdir sharedir | |
221 | ||
222 | # Parse options. | |
223 | parse_args [list {sepdebug} {shared}] | |
224 | ||
225 | # PROGRAM to run to generate core file. This could be different | |
226 | # than the program that was originally built, e.g., for a stripped | |
227 | # executable. | |
228 | if {$shared} { | |
229 | set builddir [standard_output_file $sharedir] | |
230 | } else { | |
231 | set builddir [standard_output_file $execdir] | |
232 | } | |
233 | set program_to_run [file join $builddir [file tail $binfile]] | |
234 | ||
235 | # A list of suffixes to use to describe the test and the .build-id | |
236 | # directory for the test. The suffix will be used, joined with spaces, | |
237 | # to prefix all tests for the given run. It will be used, joined with | |
238 | # dashes, to create a unique build-id directory. | |
239 | set suffix {} | |
240 | if {$shared} { | |
241 | lappend suffix "shared" | |
242 | } else { | |
243 | lappend suffix "exec" | |
244 | } | |
245 | ||
246 | if {$sepdebug} { | |
247 | # Strip debuginfo into its own file. | |
248 | if {[gdb_gnu_strip_debug [standard_output_file $program_to_run]] \ | |
249 | != 0} { | |
250 | untested "could not strip executable for [join $suffix \ ]" | |
251 | return | |
252 | } | |
253 | ||
254 | # Run the stripped program instead of the original. | |
255 | set program_to_run [file join $builddir \ | |
256 | [file tail "$binfile.stripped"]] | |
257 | lappend suffix "sepdebug" | |
258 | } | |
259 | ||
260 | # Find the core file. | |
261 | set corefile [core_find $program_to_run] | |
262 | if {$corefile == ""} { | |
263 | untested "could not generate core file" | |
264 | return | |
265 | } | |
266 | verbose -log "corefile is $corefile" | |
267 | ||
268 | # Grab the build-id from the binary, removing ".debug" from the end. | |
269 | set buildid [build_id_debug_filename_get $program_to_run] | |
270 | if {$buildid == ""} { | |
271 | untested "binary for [join $suffix \ ] has no build-id" | |
272 | } | |
273 | regsub {\.debug$} $buildid {} buildid | |
274 | verbose -log "build-id is $buildid" | |
275 | ||
276 | with_test_prefix "[join $suffix \ ]" { | |
277 | locate_exec_from_core_build_id $corefile $buildid \ | |
278 | [join $suffix -] $sepdebug false $shared | |
279 | } | |
280 | ||
281 | with_test_prefix "symlink [join $suffix \ ]" { | |
282 | locate_exec_from_core_build_id $corefile $buildid \ | |
283 | [join $suffix -] $sepdebug true $shared | |
284 | } | |
285 | } | |
286 | ||
287 | # Directories where executables will be moved before testing. | |
288 | set execdir "build-exec" | |
289 | set sharedir "build-shared" | |
290 | ||
291 | # | |
292 | # Do tests | |
293 | # | |
294 | ||
295 | build_corefile_buildid_exec | |
296 | do_corefile_buildid_tests | |
297 | do_corefile_buildid_tests -sepdebug | |
298 | ||
299 | if {![skip_shlib_tests]} { | |
300 | build_corefile_buildid_shared | |
301 | do_corefile_buildid_tests -shared | |
302 | do_corefile_buildid_tests -shared -sepdebug | |
303 | } |