xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.linespec/explicit.exp (revision 867d70fc718005c0918b8b8b2f9d7f2d52d0a0db)
1# Copyright 2012-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, see <http://www.gnu.org/licenses/>.
15
16# Tests for explicit locations
17
18load_lib completion-support.exp
19
20standard_testfile explicit.c explicit2.c 3explicit.c
21set exefile $testfile
22
23if {[prepare_for_testing "failed to prepare" $exefile \
24	 [list $srcfile $srcfile2 $srcfile3] {debug nowarnings}]} {
25    return -1
26}
27
28# Wrap the entire test in a namespace to avoid contaminating other tests.
29namespace eval $testfile {
30
31    # Test the given (explicit) LINESPEC which should cause gdb to break
32    # at LOCATION.
33    proc test_breakpoint {linespec location} {
34
35	set testname "set breakpoint at \"$linespec\""
36	# Delete all breakpoints, set a new breakpoint at LINESPEC,
37	# and attempt to run to it.
38	delete_breakpoints
39	if {[gdb_breakpoint $linespec]} {
40	    pass $testname
41	    send_log "\nexpecting locpattern \"$location\"\n"
42	    gdb_continue_to_breakpoint $linespec $location
43	} else {
44	    fail $testname
45	}
46    }
47
48    # Add the given LINESPEC to the array named in THEARRAY.  GDB is expected
49    # to stop at LOCATION.
50    proc add {thearray linespec location} {
51	upvar $thearray ar
52
53	lappend ar(linespecs) $linespec
54	lappend ar(locations) $location
55    }
56
57    # A list of all explicit linespec arguments.
58    variable all_arguments
59    set all_arguments {"source" "function" "label" "line"}
60
61    # Some locations used in this test
62    variable lineno
63    variable location
64    set lineno(normal) [gdb_get_line_number "myfunction location" $srcfile]
65    set lineno(top) [gdb_get_line_number "top location" $srcfile]
66    foreach v [array names lineno] {
67	set location($v) ".*[string_to_regexp "$srcfile:$lineno($v)"].*"
68    }
69
70    # A list of explicit locations and the corresponding location.
71    variable linespecs
72    set linespecs(linespecs) {}
73    set linespecs(location) {}
74
75    add linespecs "-source $srcfile -function myfunction" $location(normal)
76    add linespecs "-source $srcfile -function myfunction -label top" \
77	$location(top)
78
79    # This isn't implemented yet; -line is silently ignored.
80    add linespecs "-source $srcfile -function myfunction -label top -line 3" \
81	$location(top)
82    add linespecs "-source $srcfile -line $lineno(top)" $location(top)
83    add linespecs "-function myfunction" $location(normal)
84    add linespecs "-function myfunction -label top" $location(top)
85
86    # These are also not yet supported; -line is silently ignored.
87    add linespecs "-function myfunction -line 3" $location(normal)
88    add linespecs "-function myfunction -label top -line 3" $location(top)
89    add linespecs "-line 3" $location(normal)
90
91    # Fire up gdb.
92    if {![runto_main]} {
93	return -1
94    }
95
96    # Turn off queries
97    gdb_test_no_output "set confirm off"
98
99    # Simple error tests (many more are tested in ls-err.exp)
100    foreach arg $all_arguments {
101	# Test missing argument
102	gdb_test "break -$arg" \
103	    [string_to_regexp "missing argument for \"-$arg\""]
104
105	# Test abbreviations
106	set short [string range $arg 0 3]
107	gdb_test "break -$short" \
108	    [string_to_regexp "missing argument for \"-$short\""]
109    }
110
111    # Test invalid arguments
112    foreach arg {"-foo" "-foo bar" "-function myfunction -foo" \
113		     "-function -myfunction -foo bar"} {
114	gdb_test "break $arg" \
115	    [string_to_regexp "invalid explicit location argument, \"-foo\""]
116    }
117
118    # Test explicit locations, with and without conditions.
119    # For these tests, it is easiest to turn of pending breakpoint.
120    gdb_test_no_output "set breakpoint pending off" \
121	"turn off pending breakpoints"
122
123    foreach linespec $linespecs(linespecs) loc_pattern $linespecs(locations) {
124
125	# Test the linespec
126	test_breakpoint $linespec $loc_pattern
127
128	# Test with a valid condition
129	delete_breakpoints
130	set tst "set breakpoint at \"$linespec\" with valid condition"
131	if {[gdb_breakpoint "$linespec if arg == 0"]} {
132	    pass $tst
133
134	    gdb_test "info break" ".*stop only if arg == 0.*" \
135		"info break of conditional breakpoint at \"$linespec\""
136	} else {
137	    fail $tst
138	}
139
140	# Test with invalid condition
141	gdb_test "break $linespec if foofoofoo == 1" \
142	    ".*No symbol \"foofoofoo\" in current context.*" \
143	    "set breakpoint at \"$linespec\" with invalid condition"
144
145	# Test with thread
146	delete_breakpoints
147	gdb_test "break $linespec thread 123" "Unknown thread 123."
148    }
149
150    # Tests below are about tab-completion, which doesn't work if readline
151    # library isn't used.  Check it first.
152    if { [readline_is_used] } {
153
154	# Test the explicit location completer
155	foreach abbrev {"fun" "so" "lab" "li"}  full {"function" "source" "label" "line"} {
156	    set tst "complete 'break -$abbrev'"
157	    send_gdb "break -${abbrev}\t"
158	    gdb_test_multiple "" $tst {
159		-re "break -$full " {
160		    send_gdb "\n"
161		    gdb_test_multiple "" $tst {
162			-re "missing argument for \"-$full\".*$gdb_prompt " {
163			    pass $tst
164			}
165		    }
166		}
167	    }
168	    set tst "complete -$full with no value"
169	    send_gdb "break -$full \t"
170	    gdb_test_multiple "" $tst {
171		-re ".*break -$full " {
172		    send_gdb "\n"
173		    gdb_test_multiple "" $tst {
174			-re ".*Source filename requires function, label, or line offset\..*$gdb_prompt " {
175			    if {[string equal $full "source"]} {
176				pass $tst
177			    } else {
178				fail $tst
179			    }
180			}
181			-re "missing argument for \"-$full\".*$gdb_prompt " {
182			    pass $tst
183			}
184		    }
185		}
186	    }
187	}
188
189	set tst "complete unique function name"
190	send_gdb "break -function my_unique_func\t"
191	gdb_test_multiple "" $tst {
192	    -re "break -function my_unique_function_name" {
193		send_gdb "\n"
194		gdb_test "" ".*Breakpoint \[0-9\]+.*" $tst
195		gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
196	    }
197	}
198
199	set tst "complete non-unique function name"
200	send_gdb "break -function myfunc\t"
201	gdb_test_multiple "" $tst {
202	    -re "break -function myfunc\\\x07tion" {
203		send_gdb "\t\t"
204		gdb_test_multiple "" $tst {
205		    -re "\\\x07\r\nmyfunction\[ \t\]+myfunction2\[ \t\]+myfunction3\[ \t\]+myfunction4\[ \t\]+\r\n$gdb_prompt " {
206			gdb_test "2" ".*Breakpoint \[0-9\]+.*" $tst
207			gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
208		    }
209		}
210	    }
211	}
212
213	set tst "complete non-existant function name"
214	send_gdb "break -function foo\t"
215	gdb_test_multiple "" $tst {
216	    -re "break -function foo\\\x07" {
217		send_gdb "\t\t"
218		gdb_test_multiple "" $tst {
219		    -re "\\\x07\\\x07" {
220			send_gdb "\n"
221			gdb_test "" {Function "foo" not defined.} $tst
222		    }
223		}
224	    }
225	}
226
227	with_test_prefix "complete unique file name" {
228	    foreach qc $completion::maybe_quoted_list {
229		set cmd "break -source ${qc}3explicit.c${qc}"
230		test_gdb_complete_unique \
231		    "break -source ${qc}3ex" \
232		    $cmd
233		gdb_test $cmd \
234		    {Source filename requires function, label, or line offset.}
235	    }
236	}
237
238	set tst "complete non-unique file name"
239	send_gdb "break -source exp\t"
240	gdb_test_multiple "" $tst {
241	    -re "break -source exp\\\x07licit" {
242		send_gdb "\t\t"
243		gdb_test_multiple "" $tst {
244		    -re "\\\x07\r\nexplicit.c\[ \t\]+explicit2.c\[ \t\]+\r\n$gdb_prompt" {
245			send_gdb "\n"
246			gdb_test "" \
247			    {Source filename requires function, label, or line offset.} \
248			    $tst
249		    }
250		}
251	    }
252
253	    -re "break -source exp\\\x07l" {
254		# This pattern may occur when glibc debuginfo is installed.
255		send_gdb "\t\t"
256		gdb_test_multiple "" $tst {
257		    -re "\\\x07\r\nexplicit.c\[ \t\]+explicit2.c\[ \t\]+expl.*\r\n$gdb_prompt" {
258			send_gdb "\n"
259			gdb_test "" \
260			    {Source filename requires function, label, or line offset.} \
261			    $tst
262		    }
263		}
264	    }
265	}
266
267	set tst "complete non-existant file name"
268	send_gdb "break -source foo\t"
269	gdb_test_multiple "" $tst {
270	    -re "break -source foo" {
271		send_gdb "\t\t"
272		gdb_test_multiple "" $tst {
273		    -re "\\\x07\\\x07" {
274			send_gdb "\n"
275			gdb_test "" \
276			    {Source filename requires function, label, or line offset.} \
277			    $tst
278		    }
279		}
280	    }
281	}
282
283	set tst "complete filename and unique function name"
284	send_gdb "break -source explicit.c -function ma\t"
285	gdb_test_multiple "" $tst {
286	    -re "break -source explicit.c -function main " {
287		send_gdb "\n"
288		gdb_test "" ".*Breakpoint .*" $tst
289		gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
290	    }
291	}
292
293	set tst "complete filename and non-unique function name"
294	send_gdb "break -so 3explicit.c -func myfunc\t"
295	gdb_test_multiple "" $tst {
296	    -re "break -so 3explicit.c -func myfunc\\\x07tion" {
297		send_gdb "\t\t"
298		gdb_test_multiple "" $tst {
299		    -re "\\\x07\r\nmyfunction3\[ \t\]+myfunction4\[ \t\]+\r\n$gdb_prompt " {
300			gdb_test "3" ".*Breakpoint \[0-9\]+.*" $tst
301			gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
302		    }
303		}
304	    }
305	}
306
307	set tst "complete filename and non-existant function name"
308	send_gdb "break -sou 3explicit.c -fun foo\t"
309	gdb_test_multiple "" $tst {
310	    -re "break -sou 3explicit.c -fun foo\\\x07" {
311		send_gdb "\t\t"
312		gdb_test_multiple "" $tst {
313		    -re "\\\x07\\\x07" {
314			send_gdb "\n"
315			gdb_test "" \
316			    {Function "foo" not defined in "3explicit.c".} $tst
317		    }
318		}
319	    }
320	}
321
322	set tst "complete filename and function reversed"
323	send_gdb "break -func myfunction4 -source 3ex\t"
324	gdb_test_multiple "" $tst {
325	    -re "break -func myfunction4 -source 3explicit.c " {
326		send_gdb "\n"
327		gdb_test "" "Breakpoint \[0-9\]+.*" $tst
328		gdb_test_no_output "delete \$bpnum" "delete $tst breakpoint"
329	    }
330	}
331
332	with_test_prefix "complete unique label name" {
333	    foreach qc $completion::maybe_quoted_list {
334		test_gdb_complete_unique \
335		    "break -function myfunction -label ${qc}to" \
336		    "break -function myfunction -label ${qc}top${qc}"
337	    }
338	}
339
340	with_test_prefix "complete unique label name with source file" {
341	    test_gdb_complete_unique \
342		"break -source explicit.c -function myfunction -label to" \
343		"break -source explicit.c -function myfunction -label top"
344	}
345
346	with_test_prefix "complete unique label name reversed" {
347	    test_gdb_complete_multiple "b -label top -function " "myfunction" "" {
348		"myfunction"
349		"myfunction2"
350		"myfunction3"
351		"myfunction4"
352	    }
353	}
354
355	with_test_prefix "complete non-unique label name" {
356	    test_gdb_complete_multiple "b -function myfunction -label " "" "" {
357		"done"
358		"top"
359	    }
360	}
361
362	# The program is stopped at myfunction, so gdb is able to
363	# infer the label's function.
364	with_test_prefix "complete label name with no function" {
365	    test_gdb_complete_unique \
366		"break -label to" \
367		"break -label top"
368	    check_bp_locations_match_list \
369		"break -label top" {
370		    "-function myfunction -label top"
371		}
372	}
373
374	# See above.
375	with_test_prefix "complete label name with source file but no function" {
376	    test_gdb_complete_unique \
377		"break -source explicit.c -label to" \
378		"break -source explicit.c -label top"
379	    check_bp_locations_match_list \
380		"break -source explicit.c -label top" {
381		    "-source explicit.c -function myfunction -label top"
382		}
383	}
384
385	with_test_prefix "complete label name with wrong source file" {
386	    test_gdb_complete_none \
387		"break -source explicit2.c -function myfunction -label to"
388	    check_setting_bp_fails \
389		"break -source explicit2.c -function myfunction -label top"
390	}
391
392	# Get rid of symbols from shared libraries, otherwise
393	# "b -source thr<tab>" could find some system library's
394	# source.
395	gdb_test_no_output "nosharedlibrary"
396
397	# Test that after a seemingly finished option argument,
398	# completion matches both the explicit location options and
399	# the linespec keywords.
400	set completions_list {
401	    "-function"
402	    "-label"
403	    "-line"
404	    "-qualified"
405	    "-source"
406	    "if"
407	    "task"
408	    "thread"
409	}
410	foreach what { "-function" "-label" "-line" "-source" } {
411	    # Also test with "-qualified" appearing before the
412	    # explicit location.
413	    foreach prefix {"" "-qualified "} {
414
415		# ... and with "-qualified" appearing after the
416		# explicit location.
417		foreach suffix {"" " -qualified"} {
418		    with_test_prefix "complete after $prefix$what$suffix" {
419			if {$what != "-line"} {
420			    set w "$prefix$what argument$suffix "
421			    test_gdb_complete_multiple \
422				"b $w" "" "" $completions_list
423			    test_gdb_complete_unique \
424				"b $w thr" \
425				"b $w thread"
426			    test_gdb_complete_unique \
427				"b $w -fun" \
428				"b $w -function"
429			} else {
430			    # After -line, we expect a number / offset.
431			    foreach line {"10" "+10" "-10"} {
432				set w "$prefix-line $line$suffix"
433				test_gdb_complete_multiple \
434				    "b $w " "" "" $completions_list
435				test_gdb_complete_unique \
436				    "b $w thr" \
437				    "b $w thread"
438				test_gdb_complete_unique \
439				    "b $w -fun" \
440				    "b $w -function"
441			    }
442
443			    # With an invalid -line argument, we don't get any
444			    # completions.
445			    test_gdb_complete_none "b $prefix-line argument$suffix "
446			}
447
448		    }
449
450		}
451
452		# These tests don't make sense with "-qualified" after
453		# the location.
454		with_test_prefix "complete after $prefix$what" {
455		    # Don't complete a linespec keyword ("thread") or
456		    # another option name when expecting an option
457		    # argument.
458		    test_gdb_complete_none "b $prefix$what thr"
459		    test_gdb_complete_none "b $prefix$what -fun"
460		}
461	    }
462	}
463
464	# Tests that ensure that after "if" we complete on expressions
465	# are in cpcompletion.exp.
466
467	# Disable the completion limit for the rest of the testcase.
468	gdb_test_no_output "set max-completions unlimited"
469
470	# Get rid of symbols from shared libraries, otherwise the
471	# completions match list for "break <tab>" is huge and makes
472	# the test below quite long while the gdb_test_multiple loop
473	# below consumes the matches.  Not doing this added ~20
474	# seconds at the time of writing.  (Actually, already done above.)
475	# gdb_test_no_output "nosharedlibrary"
476
477	# Test completion with no input argument.  We should see all
478	# the options, plus all the functions.  To keep it simple, as
479	# proxy, we check for presence of one explicit location
480	# option, one probe location, and one function.
481	set saw_opt_function 0
482	set saw_opt_probe_stap 0
483	set saw_function 0
484
485	set tst "complete with no arguments"
486	send_gdb "break \t"
487	gdb_test_multiple "" $tst {
488	    "break \\\x07" {
489		send_gdb "\t\t"
490		gdb_test_multiple "" $tst {
491		    "Display all" {
492			send_gdb "y"
493			exp_continue
494		    }
495		    -re "-function" {
496			set saw_opt_function 1
497			exp_continue
498		    }
499		    -re "-probe-stap" {
500			set saw_opt_probe_stap 1
501			exp_continue
502		    }
503		    -re "myfunction4" {
504			set saw_function 1
505			exp_continue
506		    }
507		    -re "\r\n$gdb_prompt " {
508			gdb_assert {$saw_opt_function && $saw_opt_probe_stap && $saw_function} $tst
509		    }
510		    -re "  " {
511			exp_continue
512		    }
513		}
514	    }
515	}
516	clear_input_line $tst
517
518	# NOTE: We don't bother testing more elaborate combinations of options,
519	# such as "-func main -sour 3ex\t" (main is defined in explicit.c).
520	# The completer cannot handle these yet.
521
522	# The following completion tests require having no symbols
523	# loaded.
524	gdb_exit
525	gdb_start
526
527	# The match list you get when you complete with no options
528	# specified at all.
529	set completion_list {
530	    "-function"
531	    "-label"
532	    "-line"
533	    "-probe"
534	    "-probe-dtrace"
535	    "-probe-stap"
536	    "-qualified"
537	    "-source"
538	}
539	with_test_prefix "complete with no arguments and no symbols" {
540	    test_gdb_complete_multiple "b " "" "-" $completion_list
541	    test_gdb_complete_multiple "b " "-" "" $completion_list
542	}
543    }
544    # End of completion tests.
545
546    # Test pending explicit breakpoints
547    gdb_exit
548    gdb_start
549
550    set tst "pending invalid conditional explicit breakpoint"
551    if {![gdb_breakpoint "-func myfunction if foofoofoo == 1" \
552	      allow-pending]} {
553	fail "set $tst"
554    } else {
555	gdb_test "info break" ".*PENDING.*myfunction if foofoofoo == 1.*" $tst
556    }
557
558    gdb_exit
559    gdb_start
560
561    set tst "pending valid conditional explicit breakpoint"
562    if {![gdb_breakpoint "-func myfunction if arg == 0" \
563	      allow-pending]} {
564	fail "set $tst"
565    } else {
566	gdb_test "info break" ".*PENDING.*myfunction if arg == 0" $tst
567
568	gdb_load [standard_output_file $exefile]
569	gdb_test "info break" \
570	    ".*in myfunction at .*$srcfile:.*stop only if arg == 0.*" \
571	    "$tst resolved"
572    }
573
574    # Test interaction of condition command and explicit linespec conditons.
575    gdb_exit
576    gdb_start
577    gdb_load [standard_output_file $exefile]
578
579    set tst "condition_command overrides explicit linespec condition"
580    if {![runto main]} {
581	fail $tst
582    } else {
583	if {![gdb_breakpoint "-func myfunction if arg == 1"]} {
584	    fail "set breakpoint with condition 'arg == 1'"
585	} else {
586	    gdb_test_no_output "cond 2 arg == 0" \
587		"set new breakpoint condition for explicit linespec"
588
589	    gdb_continue_to_breakpoint $tst $location(normal)
590	}
591    }
592
593    gdb_test "cond 2" [string_to_regexp "Breakpoint 2 now unconditional."] \
594	"clear condition for explicit breakpoint"
595    set tst "info break of cleared condition of explicit breakpoint"
596    gdb_test_multiple "info break" $tst {
597	-re ".*in myfunction at .*$srcfile:.*stop only if arg == 0.*" {
598	    fail $tst
599	}
600	-re ".*in myfunction at .*$srcfile:.*$gdb_prompt $" {
601	    pass $tst
602	}
603    }
604
605    # Test explicit "ranges."  Make sure that using explicit
606    # locations doesn't alter the expected outcome.
607    gdb_test "list main" ".*" "list main 1"
608    set list_result [capture_command_output "list -,+" ""]
609    gdb_test "list main" ".*" "list main 2"
610    gdb_test "list -line -,-line +" [string_to_regexp $list_result]
611
612    # Ditto for the reverse (except that no output is expected).
613    gdb_test "list myfunction" ".*" "list myfunction 1"
614    gdb_test_no_output "list +,-"
615    gdb_test "list myfunction" ".*" "list myfunction 2"
616    gdb_test_no_output "list -line +, -line -"
617}
618
619namespace delete $testfile
620