xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.linespec/explicit.exp (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1# Copyright 2012-2017 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# Tests for explicit locations
17
18standard_testfile explicit.c explicit2.c 3explicit.c
19set exefile $testfile
20
21if {[prepare_for_testing "failed to prepare" $exefile \
22	 [list $srcfile $srcfile2 $srcfile3] {debug nowarnings}]} {
23    return -1
24}
25
26# Wrap the entire test in a namespace to avoid contaminating other tests.
27namespace eval $testfile {
28
29    # Test the given (explicit) LINESPEC which should cause gdb to break
30    # at LOCATION.
31    proc test_breakpoint {linespec location} {
32
33	set testname "set breakpoint at \"$linespec\""
34	# Delete all breakpoints, set a new breakpoint at LINESPEC,
35	# and attempt to run to it.
36	delete_breakpoints
37	if {[gdb_breakpoint $linespec]} {
38	    pass $testname
39	    send_log "\nexpecting locpattern \"$location\"\n"
40	    gdb_continue_to_breakpoint $linespec $location
41	} else {
42	    fail $testname
43	}
44    }
45
46    # Add the given LINESPEC to the array named in THEARRAY.  GDB is expected
47    # to stop at LOCATION.
48    proc add {thearray linespec location} {
49	upvar $thearray ar
50
51	lappend ar(linespecs) $linespec
52	lappend ar(locations) $location
53    }
54
55    # A list of all explicit linespec arguments.
56    variable all_arguments
57    set all_arguments {"source" "function" "label" "line"}
58
59    # Some locations used in this test
60    variable lineno
61    variable location
62    set lineno(normal) [gdb_get_line_number "myfunction location" $srcfile]
63    set lineno(top) [gdb_get_line_number "top location" $srcfile]
64    foreach v [array names lineno] {
65	set location($v) ".*[string_to_regexp "$srcfile:$lineno($v)"].*"
66    }
67
68    # A list of explicit locations and the corresponding location.
69    variable linespecs
70    set linespecs(linespecs) {}
71    set linespecs(location) {}
72
73    add linespecs "-source $srcfile -function myfunction" $location(normal)
74    add linespecs "-source $srcfile -function myfunction -label top" \
75	$location(top)
76
77    # This isn't implemented yet; -line is silently ignored.
78    add linespecs "-source $srcfile -function myfunction -label top -line 3" \
79	$location(top)
80    add linespecs "-source $srcfile -line $lineno(top)" $location(top)
81    add linespecs "-function myfunction" $location(normal)
82    add linespecs "-function myfunction -label top" $location(top)
83
84    # These are also not yet supported; -line is silently ignored.
85    add linespecs "-function myfunction -line 3" $location(normal)
86    add linespecs "-function myfunction -label top -line 3" $location(top)
87    add linespecs "-line 3" $location(normal)
88
89    # Fire up gdb.
90    if {![runto_main]} {
91	return -1
92    }
93
94    # Turn off queries
95    gdb_test_no_output "set confirm off"
96
97    # Simple error tests (many more are tested in ls-err.exp)
98    foreach arg $all_arguments {
99	# Test missing argument
100	gdb_test "break -$arg" \
101	    [string_to_regexp "missing argument for \"-$arg\""]
102
103	# Test abbreviations
104	set short [string range $arg 0 3]
105	gdb_test "break -$short" \
106	    [string_to_regexp "missing argument for \"-$short\""]
107    }
108
109    # Test invalid arguments
110    foreach arg {"-foo" "-foo bar" "-function myfunction -foo" \
111		     "-function -myfunction -foo bar"} {
112	gdb_test "break $arg" \
113	    [string_to_regexp "invalid explicit location argument, \"-foo\""]
114    }
115
116    # Test explicit locations, with and without conditions.
117    # For these tests, it is easiest to turn of pending breakpoint.
118    gdb_test_no_output "set breakpoint pending off" \
119	"turn off pending breakpoints"
120
121    foreach linespec $linespecs(linespecs) loc_pattern $linespecs(locations) {
122
123	# Test the linespec
124	test_breakpoint $linespec $loc_pattern
125
126	# Test with a valid condition
127	delete_breakpoints
128	set tst "set breakpoint at \"$linespec\" with valid condition"
129	if {[gdb_breakpoint "$linespec if arg == 0"]} {
130	    pass $tst
131
132	    gdb_test "info break" ".*stop only if arg == 0.*" \
133		"info break of conditional breakpoint at \"$linespec\""
134	} else {
135	    fail $tst
136	}
137
138	# Test with invalid condition
139	gdb_test "break $linespec if foofoofoo == 1" \
140	    ".*No symbol \"foofoofoo\" in current context.*" \
141	    "set breakpoint at \"$linespec\" with invalid condition"
142
143	# Test with thread
144	delete_breakpoints
145	gdb_test "break $linespec thread 123" "Unknown thread 123."
146    }
147
148    # Tests below are about tab-completion, which doesn't work if readline
149    # library isn't used.  Check it first.
150    if { [readline_is_used] } {
151
152	# Test the explicit location completer
153	foreach abbrev {"fun" "so" "lab" "li"}  full {"function" "source" "label" "line"} {
154	    set tst "complete 'break -$abbrev'"
155	    send_gdb "break -${abbrev}\t"
156	    gdb_test_multiple "" $tst {
157		-re "break -$full " {
158		    send_gdb "\n"
159		    gdb_test_multiple "" $tst {
160			-re "missing argument for \"-$full\".*$gdb_prompt " {
161			    pass $tst
162			}
163		    }
164		}
165	    }
166	    set tst "complete -$full with no value"
167	    send_gdb "break -$full \t"
168	    gdb_test_multiple "" $tst {
169		-re ".*break -$full " {
170		    send_gdb "\n"
171		    gdb_test_multiple "" $tst {
172			-re ".*Source filename requires function, label, or line offset\..*$gdb_prompt " {
173			    if {[string equal $full "source"]} {
174				pass $tst
175			    } else {
176				fail $tst
177			    }
178			}
179			-re "missing argument for \"-$full\".*$gdb_prompt " {
180			    pass $tst
181			}
182		    }
183		}
184	    }
185	}
186
187	set tst "complete unique function name"
188	send_gdb "break -function my_unique_func\t"
189	gdb_test_multiple "" $tst {
190	    -re "break -function my_unique_function_name" {
191		send_gdb "\n"
192		gdb_test "" ".*Breakpoint \[0-9\]+.*" $tst
193		gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
194	    }
195	}
196
197	set tst "complete non-unique function name"
198	send_gdb "break -function myfunc\t"
199	gdb_test_multiple "" $tst {
200	    -re "break -function myfunc\\\x07tion" {
201		send_gdb "\t\t"
202		gdb_test_multiple "" $tst {
203		    -re "\\\x07\r\nmyfunction\[ \t\]+myfunction2\[ \t\]+myfunction3\[ \t\]+myfunction4\[ \t\]+\r\n$gdb_prompt " {
204			gdb_test "2" ".*Breakpoint \[0-9\]+.*" $tst
205			gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
206		    }
207		}
208	    }
209	}
210
211	set tst "complete non-existant function name"
212	send_gdb "break -function foo\t"
213	gdb_test_multiple "" $tst {
214	    -re "break -function foo\\\x07" {
215		send_gdb "\t\t"
216		gdb_test_multiple "" $tst {
217		    -re "\\\x07\\\x07" {
218			send_gdb "\n"
219			gdb_test "" {Function "foo" not defined.} $tst
220		    }
221		}
222	    }
223	}
224
225	set tst "complete unique file name"
226	send_gdb "break -source 3ex\t"
227	gdb_test_multiple "" $tst {
228	    -re "break -source 3explicit.c " {
229		send_gdb "\n"
230		gdb_test "" \
231		    {Source filename requires function, label, or line offset.} $tst
232	    }
233	}
234
235	set tst "complete non-unique file name"
236	send_gdb "break -source exp\t"
237	gdb_test_multiple "" $tst {
238	    -re "break -source exp\\\x07licit" {
239		send_gdb "\t\t"
240		gdb_test_multiple "" $tst {
241		    -re "\\\x07\r\nexplicit.c\[ \t\]+explicit2.c\[ \t\]+\r\n$gdb_prompt" {
242			send_gdb "\n"
243			gdb_test "" \
244			    {Source filename requires function, label, or line offset.} \
245			    $tst
246		    }
247		}
248	    }
249
250	    -re "break -source exp\\\x07l" {
251		# This pattern may occur when glibc debuginfo is installed.
252		send_gdb "\t\t"
253		gdb_test_multiple "" $tst {
254		    -re "\\\x07\r\nexplicit.c\[ \t\]+explicit2.c\[ \t\]+expl.*\r\n$gdb_prompt" {
255			send_gdb "\n"
256			gdb_test "" \
257			    {Source filename requires function, label, or line offset.} \
258			    $tst
259		    }
260		}
261	    }
262	}
263
264	set tst "complete non-existant file name"
265	send_gdb "break -source foo\t"
266	gdb_test_multiple "" $tst {
267	    -re "break -source foo" {
268		send_gdb "\t\t"
269		gdb_test_multiple "" $tst {
270		    -re "\\\x07\\\x07" {
271			send_gdb "\n"
272			gdb_test "" \
273			    {Source filename requires function, label, or line offset.} \
274			    $tst
275		    }
276		}
277	    }
278	}
279
280	set tst "complete filename and unique function name"
281	send_gdb "break -source explicit.c -function ma\t"
282	gdb_test_multiple "" $tst {
283	    -re "break -source explicit.c -function main " {
284		send_gdb "\n"
285		gdb_test "" ".*Breakpoint .*" $tst
286		gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
287	    }
288	}
289
290	set tst "complete filename and non-unique function name"
291	send_gdb "break -so 3explicit.c -func myfunc\t"
292	gdb_test_multiple "" $tst {
293	    -re "break -so 3explicit.c -func myfunc\\\x07tion" {
294		send_gdb "\t\t"
295		gdb_test_multiple "" $tst {
296		    -re "\\\x07\r\nmyfunction3\[ \t\]+myfunction4\[ \t\]+\r\n$gdb_prompt " {
297			gdb_test "3" ".*Breakpoint \[0-9\]+.*" $tst
298			gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
299		    }
300		}
301	    }
302	}
303
304	set tst "complete filename and non-existant function name"
305	send_gdb "break -sou 3explicit.c -fun foo\t"
306	gdb_test_multiple "" $tst {
307	    -re "break -sou 3explicit.c -fun foo\\\x07" {
308		send_gdb "\t\t"
309		gdb_test_multiple "" $tst {
310		    -re "\\\x07\\\x07" {
311			send_gdb "\n"
312			gdb_test "" \
313			    {Function "foo" not defined in "3explicit.c".} $tst
314		    }
315		}
316	    }
317	}
318
319	set tst "complete filename and function reversed"
320	send_gdb "break -func myfunction4 -source 3ex\t"
321	gdb_test_multiple "" $tst {
322	    -re "break -func myfunction4 -source 3explicit.c " {
323		send_gdb "\n"
324		gdb_test "" "Breakpoint \[0-9\]+.*" $tst
325		gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
326	    }
327	}
328
329	# NOTE: We don't bother testing more elaborate combinations of options,
330	# such as "-func main -sour 3ex\t" (main is defined in explicit.c).
331	# The completer cannot handle these yet.
332
333    }
334    # End of completion tests.
335
336    # Test pending explicit breakpoints
337    gdb_exit
338    gdb_start
339
340    set tst "pending invalid conditional explicit breakpoint"
341    if {![gdb_breakpoint "-func myfunction if foofoofoo == 1" \
342	      allow-pending]} {
343	fail "set $tst"
344    } else {
345	gdb_test "info break" ".*PENDING.*myfunction if foofoofoo == 1.*" $tst
346    }
347
348    gdb_exit
349    gdb_start
350
351    set tst "pending valid conditional explicit breakpoint"
352    if {![gdb_breakpoint "-func myfunction if arg == 0" \
353	      allow-pending]} {
354	fail "set $tst"
355    } else {
356	gdb_test "info break" ".*PENDING.*myfunction if arg == 0" $tst
357
358	gdb_load [standard_output_file $exefile]
359	gdb_test "info break" \
360	    ".*in myfunction at .*$srcfile:.*stop only if arg == 0.*" \
361	    "$tst resolved"
362    }
363
364    # Test interaction of condition command and explicit linespec conditons.
365    gdb_exit
366    gdb_start
367    gdb_load [standard_output_file $exefile]
368
369    set tst "condition_command overrides explicit linespec condition"
370    if {![runto main]} {
371	fail $tst
372    } else {
373	if {![gdb_breakpoint "-func myfunction if arg == 1"]} {
374	    fail "set breakpoint with condition 'arg == 1'"
375	} else {
376	    gdb_test_no_output "cond 2 arg == 0" \
377		"set new breakpoint condition for explicit linespec"
378
379	    gdb_continue_to_breakpoint $tst $location(normal)
380	}
381    }
382
383    gdb_test "cond 2" [string_to_regexp "Breakpoint 2 now unconditional."] \
384	"clear condition for explicit breakpoint"
385    set tst "info break of cleared condition of explicit breakpoint"
386    gdb_test_multiple "info break" $tst {
387	-re ".*in myfunction at .*$srcfile:.*stop only if arg == 0.*" {
388	    fail $tst
389	}
390	-re ".*in myfunction at .*$srcfile:.*$gdb_prompt $" {
391	    pass $tst
392	}
393    }
394
395    # Test explicit "ranges."  Make sure that using explicit
396    # locations doesn't alter the expected outcome.
397    gdb_test "list main" ".*" "list main 1"
398    set list_result [capture_command_output "list -,+" ""]
399    gdb_test "list main" ".*" "list main 2"
400    gdb_test "list -line -,-line +" [string_to_regexp $list_result]
401
402    # Ditto for the reverse (except that no output is expected).
403    gdb_test "list myfunction" ".*" "list myfunction 1"
404    gdb_test_no_output "list +,-"
405    gdb_test "list myfunction" ".*" "list myfunction 2"
406    gdb_test_no_output "list -line +, -line -"
407}
408
409namespace delete $testfile
410