xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.python/py-breakpoint.exp (revision 22ebeae4b2252475e0ebe332f69734639cb946ea)
1# Copyright (C) 2010-2023 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# This file is part of the GDB testsuite.  It tests the mechanism
17# exposing breakpoints to Python.
18
19# The skip_hw_watchpoint_tests checks if watchpoints are supported by the
20# processor.  On PowerPC, the check runs a small test program under gdb
21# to determine if the Power processor supports HW watchpoints.  The check
22# must be done before starting the test so as to not disrupt the execution
23# of the actual test.
24
25set skip_hw_watchpoint_tests_p [skip_hw_watchpoint_tests]
26
27load_lib gdb-python.exp
28
29standard_testfile
30
31set options {debug c++}
32
33if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} ${options}] } {
34    return -1
35}
36
37# Skip all tests if Python scripting is not enabled.
38if { [skip_python_tests] } { continue }
39
40proc_with_prefix test_bkpt_basic { } {
41    global srcfile testfile hex decimal
42
43    # Start with a fresh gdb.
44    clean_restart ${testfile}
45
46    # We should start with no breakpoints.
47    gdb_test "python print (gdb.breakpoints())" "\\(\\)"
48
49    if {![runto_main]} {
50	return 0
51    }
52
53    # Now there should be one breakpoint: main.
54    gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" \
55	"Get Breakpoint List" 0
56    gdb_test "python print (blist\[0\])" \
57	"<gdb.Breakpoint object at $hex>" "Check obj exists @main"
58    gdb_test "python print (blist\[0\].location)" \
59	"main." "Check breakpoint location @main"
60    gdb_test "python print (blist\[0\].pending)" "False" \
61	"Check pending status of main breakpoint"
62
63    set mult_line [gdb_get_line_number "Break at multiply."]
64    gdb_breakpoint ${mult_line}
65    gdb_continue_to_breakpoint "Break at multiply" \
66	".*Break at multiply.*"
67
68    # Check that the Python breakpoint code noted the addition of a
69    # breakpoint "behind the scenes".
70    gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" \
71	"Get Breakpoint List" 0
72    gdb_test "python print (len(blist))" \
73	"2" "Check for two breakpoints"
74    gdb_test "python print (blist\[0\])" \
75	"<gdb.Breakpoint object at $hex>" "Check obj exists @main 2"
76    gdb_test "python print (blist\[0\].location)" \
77	"main." "Check breakpoint location @main 2"
78    gdb_test "python print (blist\[1\])" \
79	"<gdb.Breakpoint object at $hex>" "Check obj exists @mult_line"
80
81    gdb_test "python print (blist\[1\].location)" \
82	"py-breakpoint\.c:${mult_line}*" \
83	"check breakpoint location @mult_line"
84
85    # Check hit and ignore counts.
86    gdb_test "python print (blist\[1\].hit_count)" \
87	"1" "Check breakpoint hit count @1"
88    gdb_py_test_silent_cmd "python blist\[1\].ignore_count = 4" \
89	"Set breakpoint hit count" 0
90    gdb_continue_to_breakpoint "Break at multiply @6" \
91	".*Break at multiply.*"
92    gdb_test "python print (blist\[1\].hit_count)" \
93	"6" "Check breakpoint hit count @6"
94    gdb_test "print result" \
95	" = 545" "Check expected variable result after 6 iterations"
96
97    # Test breakpoint is enabled and disabled correctly..
98    gdb_breakpoint [gdb_get_line_number "Break at add."]
99    gdb_continue_to_breakpoint "Break at add 1" ".*Break at add.*"
100    gdb_test "python print (blist\[1\].enabled)" \
101	"True" "Check breakpoint enabled."
102    gdb_py_test_silent_cmd  "python blist\[1\].enabled = False" \
103	"Set breakpoint disabled." 0
104    gdb_continue_to_breakpoint "Break at add 2" ".*Break at add.*"
105    gdb_py_test_silent_cmd  "python blist\[1\].enabled = True" \
106	"Set breakpoint enabled." 0
107    gdb_continue_to_breakpoint "Break at multiply after re-enable" \
108	".*Break at multiply.*"
109
110    # Test other getters and setters.
111    gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" \
112	"Get Breakpoint List" 0
113    gdb_test "python print (blist\[1\].thread)" \
114	"None" "Check breakpoint thread"
115    gdb_test "python print (blist\[1\].type == gdb.BP_BREAKPOINT)" \
116	"True" "Check breakpoint type"
117    gdb_test "python print (blist\[0\].number)" \
118	"1" "Check breakpoint number 0"
119    gdb_test "python print (blist\[1\].number)" \
120	"2" "Check breakpoint number 1"
121    gdb_test "python print (blist\[2\].number)" \
122	"3" "Check breakpoint number 2"
123}
124
125proc_with_prefix test_bkpt_deletion { } {
126    global srcfile testfile hex decimal
127
128    # Start with a fresh gdb.
129    clean_restart ${testfile}
130
131    if {![runto_main]} {
132	return 0
133    }
134
135    # Test breakpoints are deleted correctly.
136    set deltst_location [gdb_get_line_number "Break at multiply."]
137    set end_location [gdb_get_line_number "Break at end."]
138    gdb_py_test_silent_cmd  "python dp1 = gdb.Breakpoint (\"$deltst_location\")" \
139	"Set breakpoint" 0
140    gdb_breakpoint [gdb_get_line_number "Break at end."]
141    gdb_py_test_silent_cmd "python del_list = gdb.breakpoints()" \
142	"Get Breakpoint List" 0
143    gdb_test "python print (len(del_list))" \
144	"3" "Number of breakpoints before delete"
145    gdb_continue_to_breakpoint "Break at multiply." \
146	".*$srcfile:$deltst_location.*"
147    gdb_py_test_silent_cmd  "python dp1.delete()" \
148	"Delete Breakpoint" 0
149    gdb_test "python print (dp1.number)" \
150	"RuntimeError: Breakpoint 2 is invalid.*" \
151	"Check breakpoint invalidated"
152    gdb_py_test_silent_cmd "python del_list = gdb.breakpoints()" \
153	"Get Breakpoint List" 0
154    gdb_test "python print (len(del_list))" \
155	"2" "Number of breakpoints after delete"
156    gdb_continue_to_breakpoint "Break at end." \
157	".*$srcfile:$end_location.*"
158}
159
160proc_with_prefix test_bkpt_cond_and_cmds { } {
161    global srcfile testfile hex decimal
162
163    # Start with a fresh gdb.
164    clean_restart ${testfile}
165
166    if {![runto_main]} {
167	return 0
168    }
169
170    # Test conditional setting.
171    set bp_location1 [gdb_get_line_number "Break at multiply."]
172    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (\"$bp_location1\")" \
173	"Set breakpoint" 0
174    gdb_continue_to_breakpoint "Break at multiply" \
175	".*Break at multiply.*"
176    gdb_py_test_silent_cmd "python bp1.condition = \"i == 5\"" \
177	"Set breakpoint" 0
178    gdb_test "python print (bp1.condition)" "i == 5" \
179	"Test conditional has been set"
180    gdb_continue_to_breakpoint "Break at multiply @5" \
181	".*Break at multiply.*"
182    gdb_test "print i" \
183	"5" "Test conditional breakpoint stopped after five iterations"
184    gdb_py_test_silent_cmd "python bp1.condition = None" \
185	"Clear condition" 0
186    gdb_test "python print (bp1.condition)" \
187	"None" "Test conditional read"
188    gdb_continue_to_breakpoint "Break at multiply @6" \
189	".*Break at multiply.*"
190    gdb_test "print i" \
191	"6" "Test breakpoint stopped after six iterations"
192
193    # Test commands.
194    gdb_breakpoint [gdb_get_line_number "Break at add."]
195    set test {commands $bpnum}
196    gdb_test_multiple $test $test { -re "\r\n>$" { pass $test } }
197    set test {print "Command for breakpoint has been executed."}
198    gdb_test_multiple $test $test { -re "\r\n>$" { pass $test } }
199    set test {print result}
200    gdb_test_multiple $test $test { -re "\r\n>$" { pass $test } }
201    gdb_test "end"
202
203    gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" \
204	"Get Breakpoint List" 0
205    gdb_py_test_silent_cmd "python last_bp = blist\[len(blist)-1\]" \
206	"Find last breakpoint" 0
207    gdb_test "python print (last_bp.commands)" \
208	"print \"Command for breakpoint has been executed.\".*print result"
209
210    gdb_test_no_output "python last_bp.commands = 'echo hi\\necho there'" \
211	"set commands"
212    # Note the length is 3 because the string ends in a \n.
213    gdb_test "python print (len(last_bp.commands.split('\\n')))" "3" \
214	"check number of lines in commands"
215}
216
217proc_with_prefix test_bkpt_invisible { } {
218    global srcfile testfile hex decimal
219
220    # Start with a fresh gdb.
221    clean_restart ${testfile}
222
223    if {![runto_main]} {
224	return 0
225    }
226
227    delete_breakpoints
228    set ibp_location [gdb_get_line_number "Break at multiply."]
229    gdb_py_test_silent_cmd  "python ibp = gdb.Breakpoint(\"$ibp_location\", internal=False)" \
230	"Set invisible breakpoint" 0
231    gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" \
232	"Get Breakpoint List" 0
233    gdb_test "python print (ilist\[0\])" \
234	"<gdb.Breakpoint object at $hex>" "Check invisible bp obj exists 1"
235    gdb_test "python print (ilist\[0\].location)" \
236	"py-breakpoint\.c:$ibp_location*" "Check breakpoint location 1"
237    gdb_test "python print (ilist\[0\].visible)" \
238	"True" "Check breakpoint visibility 1"
239    gdb_test "info breakpoints" "py-breakpoint\.c:$ibp_location.*" \
240	"Check info breakpoints shows visible breakpoints"
241    delete_breakpoints
242    gdb_py_test_silent_cmd  "python ibp = gdb.Breakpoint(\"$ibp_location\", internal=True)" \
243	"Set invisible breakpoint" 0
244    gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" \
245	"Get Breakpoint List" 0
246    gdb_test "python print (ilist\[0\])" \
247	"<gdb.Breakpoint object at $hex>" "Check invisible bp obj exists 2"
248    gdb_test "python print (ilist\[0\].location)" \
249	"py-breakpoint\.c:$ibp_location*" "Check breakpoint location 2"
250    gdb_test "python print (ilist\[0\].visible)" \
251	"False" "Check breakpoint visibility 2"
252    gdb_test "info breakpoints" "No breakpoints or watchpoints.*" \
253	"Check info breakpoints does not show invisible breakpoints"
254    gdb_test "maint info breakpoints" \
255	"py-breakpoint\.c:$ibp_location.*" \
256	"Check maint info breakpoints shows invisible breakpoints"
257}
258
259proc_with_prefix test_hardware_breakpoints { } {
260    global srcfile testfile hex decimal
261
262    # Skip these tests if the HW does not support hardware breakpoints.
263    if { [skip_hw_breakpoint_tests] } { return 0 }
264
265    # Start with a fresh gdb.
266    clean_restart ${testfile}
267
268    if {![runto_main]} {
269	return 0
270    }
271
272    delete_breakpoints
273
274    gdb_test "python hbp1 = gdb.Breakpoint(\"add\", type=gdb.BP_HARDWARE_BREAKPOINT)" \
275	".*Hardware assisted breakpoint ($decimal)+ at .*$srcfile, line ($decimal)+\." \
276	"Set hardware breakpoint"
277    gdb_test "python print (gdb.breakpoints()\[0\].type == gdb.BP_HARDWARE_BREAKPOINT)" \
278	"True" "Check hardware breakpoint type"
279    gdb_test "continue" \
280	".*Breakpoint ($decimal)+, add.*" \
281	"Test hardware breakpoint stop"
282}
283
284proc_with_prefix test_watchpoints { } {
285    global srcfile testfile hex decimal
286    global skip_hw_watchpoint_tests_p
287
288    # Start with a fresh gdb.
289    clean_restart ${testfile}
290
291    # Disable hardware watchpoints if necessary.
292    if {$skip_hw_watchpoint_tests_p} {
293	gdb_test_no_output "set can-use-hw-watchpoints 0" ""
294    }
295
296    if {![runto_main]} {
297	return 0
298    }
299
300    gdb_py_test_silent_cmd  "python wp1 = gdb.Breakpoint (\"result\", type=gdb.BP_WATCHPOINT, wp_class=gdb.WP_WRITE )" \
301	"Set watchpoint" 0
302    gdb_test "python print (wp1.pending)" "False"
303    gdb_test "continue" \
304	".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*main.*" \
305	"Test watchpoint write"
306}
307
308proc_with_prefix test_bkpt_internal { } {
309    global srcfile testfile hex decimal
310    global skip_hw_watchpoint_tests_p
311
312    # Start with a fresh gdb.
313    clean_restart ${testfile}
314
315    # Disable hardware watchpoints if necessary.
316    if {$skip_hw_watchpoint_tests_p} {
317	gdb_test_no_output "set can-use-hw-watchpoints 0" ""
318    }
319    if {![runto_main]} {
320	return 0
321    }
322    delete_breakpoints
323    gdb_py_test_silent_cmd  "python bp1 = gdb.Breakpoint (\"main\", type=gdb.BP_BREAKPOINT, wp_class=gdb.WP_WRITE, internal=True )" \
324	"Set internal breakpoint" 0
325
326    set bp_num [get_python_valueof bp1.number "*DEFAULT*"]
327    set bp_addr [gdb_get_bp_addr $bp_num]
328
329    gdb_test "maint info break $bp_num" \
330	"$bp_num.*$bp_addr.*" \
331	"maint info breakpoint \$bp_num"
332
333    gdb_test "python gdb.execute(\'clear *$bp_addr\')" \
334	".*No breakpoint at \\*$bp_addr.*" \
335	"clear internal breakpoint"
336
337    # Check again, make sure that GDB really didn't delete the internal breakpoint.
338    gdb_test "maint info break $bp_num" \
339	"$bp_num.*$bp_addr.*" \
340	"maint info breakpoint \$bp_num after clear"
341
342    delete_breakpoints
343    gdb_py_test_silent_cmd  "python wp1 = gdb.Breakpoint (\"result\", type=gdb.BP_WATCHPOINT, wp_class=gdb.WP_WRITE, internal=True )" \
344	"Set watchpoint" 0
345    gdb_test "info breakpoints" \
346	"No breakpoints or watchpoints.*" \
347	"Check info breakpoints does not show invisible breakpoints"
348    gdb_test "maint info breakpoints" \
349	".*watchpoint.*result.*" \
350	"Check maint info breakpoints shows invisible breakpoints"
351    gdb_test "continue" \
352	".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*" \
353	"Test watchpoint write"
354}
355
356proc_with_prefix test_bkpt_eval_funcs { } {
357    global srcfile testfile hex decimal
358    global skip_hw_watchpoint_tests_p
359
360    # Start with a fresh gdb.
361    clean_restart ${testfile}
362
363    # Disable hardware watchpoints if necessary.
364    if {$skip_hw_watchpoint_tests_p} {
365	gdb_test_no_output "set can-use-hw-watchpoints 0" ""
366    }
367    if {![runto_main]} {
368	return 0
369    }
370    delete_breakpoints
371
372    gdb_test_multiline "Sub-class a breakpoint" \
373	"python" "" \
374	"class bp_eval (gdb.Breakpoint):" "" \
375	"   inf_i = 0" "" \
376	"   count = 0" "" \
377	"   def stop (self):" "" \
378	"      self.count = self.count + 1" "" \
379	"      self.inf_i = gdb.parse_and_eval(\"i\")" "" \
380	"      if self.inf_i == 3:" "" \
381	"        return True" "" \
382	"      return False" "" \
383	"end" ""
384
385    gdb_test_multiline "Sub-class a second breakpoint" \
386	"python" "" \
387	"class bp_also_eval (gdb.Breakpoint):" "" \
388	"   count = 0" "" \
389	"   def stop (self):" "" \
390	"      self.count = self.count + 1" "" \
391	"      if self.count == 9:" "" \
392	"        return True" "" \
393	"      return False" "" \
394	"end" ""
395
396    gdb_test_multiline "Sub-class a third breakpoint" \
397	"python" "" \
398	"class basic (gdb.Breakpoint):" "" \
399	"   count = 0" "" \
400	"end" ""
401
402    set bp_location2 [gdb_get_line_number "Break at multiply."]
403    set end_location [gdb_get_line_number "Break at end."]
404    gdb_py_test_silent_cmd "python eval_bp1 = bp_eval(\"$bp_location2\")" \
405	"Set breakpoint" 0
406    gdb_py_test_silent_cmd "python also_eval_bp1 = bp_also_eval(\"$bp_location2\")" \
407	"Set breakpoint" 0
408    gdb_py_test_silent_cmd "python never_eval_bp1 = bp_also_eval(\"$end_location\")" \
409	"Set breakpoint" 0
410    gdb_continue_to_breakpoint "Break at multiply, i==3" \
411	".*$srcfile:$bp_location2.*"
412    gdb_test "print i" \
413	"3" "Check inferior value matches python accounting"
414    gdb_test "python print (eval_bp1.inf_i)" \
415	"3" "Check python accounting matches inferior"
416    gdb_test "python print (also_eval_bp1.count)" "4" \
417	"Check non firing same-location also_eval_bp1 function was also called at each stop."
418    gdb_test "python print (eval_bp1.count)" "4" \
419	"Check non firing same-location eval_bp1 function was also called at each stop."
420
421    delete_breakpoints
422    set cond_bp [gdb_get_line_number "Break at multiply."]
423    gdb_py_test_silent_cmd  "python eval_bp1 = bp_eval(\"$cond_bp\")" \
424	"Set breakpoint" 0
425    set test_cond {cond $bpnum}
426    gdb_test "$test_cond \"foo==3\"" \
427	"Only one stop condition allowed.  There is currently a Python.*" \
428	"Check you cannot add a CLI condition to a Python breakpoint that has defined stop"
429    gdb_py_test_silent_cmd "python eval_bp2 = basic(\"$cond_bp\")" \
430	"Set breakpoint" 0
431    gdb_py_test_silent_cmd "python eval_bp2.condition = \"1==1\"" \
432	"Set a condition" 0
433    gdb_test_multiline "Construct an eval function" \
434	"python" "" \
435	"def stop_func ():" "" \
436	"   return True" "" \
437	"end" ""
438
439    gdb_test "python eval_bp2.stop = stop_func"  \
440	"RuntimeError: Only one stop condition allowed.  There is currently a GDB.*" \
441	"assign stop function to a breakpoint that has a condition"
442
443    delete_breakpoints
444    gdb_breakpoint [gdb_get_line_number "Break at multiply."]
445    gdb_py_test_silent_cmd  "python check_eval = bp_eval(\"$bp_location2\")" \
446	"Set breakpoint" 0
447    gdb_test "python print (check_eval.count)" "0" \
448	"Test that evaluate function has not been yet executed (ie count = 0)"
449    gdb_continue_to_breakpoint "Break at multiply, count==1" \
450	".*$srcfile:$bp_location2.*"
451    gdb_test "python print (check_eval.count)" "1" \
452	"Test that evaluate function is run when location also has normal bp"
453
454    gdb_test_multiline "Sub-class a watchpoint" \
455	"python" "" \
456	"class wp_eval (gdb.Breakpoint):" "" \
457	"   def stop (self):" "" \
458	"      self.result = gdb.parse_and_eval(\"result\")" "" \
459	"      if self.result == 788:" "" \
460	"        return True" "" \
461	"      return False" "" \
462	"end" ""
463
464    delete_breakpoints
465    gdb_py_test_silent_cmd  "python wp1 = wp_eval (\"result\", type=gdb.BP_WATCHPOINT, wp_class=gdb.WP_WRITE)" \
466	"Set watchpoint" 0
467    gdb_test "continue" \
468	".*\[Ww\]atchpoint.*result.*Old value =.*New value = 788.*" \
469	"Test watchpoint write"
470    gdb_test "python print (never_eval_bp1.count)" "0" \
471	"Check that this unrelated breakpoints eval function was never called."
472}
473
474proc_with_prefix test_bkpt_temporary { } {
475    global srcfile testfile hex decimal
476
477    # Start with a fresh gdb.
478    clean_restart ${testfile}
479
480    if {![runto_main]} {
481	return 0
482    }
483    delete_breakpoints
484
485    gdb_test_multiline "Sub-class and check temporary breakpoint" \
486	"python" "" \
487	"class temp_bp (gdb.Breakpoint):" "" \
488	"   count = 0" "" \
489	"   def stop (self):" "" \
490	"      self.count = self.count + 1" "" \
491	"      return True" "" \
492	"end" ""
493    set ibp_location [gdb_get_line_number "Break at multiply."]
494    gdb_py_test_silent_cmd "python ibp = temp_bp(\"$ibp_location\", temporary=True)" \
495	"Set temporary breakpoint" 0
496    gdb_test "info breakpoints" \
497	"2.*breakpoint.*del.*py-breakpoint\.c:$ibp_location.*" \
498	"Check info breakpoints shows breakpoint with temporary status"
499    gdb_test "python print (ibp.location)" "py-breakpoint\.c:$ibp_location*" \
500	"Check temporary breakpoint location"
501    gdb_test "python print (ibp.temporary)" "True" \
502	"Check breakpoint temporary status"
503    gdb_continue_to_breakpoint "Break at multiply." \
504	".*$srcfile:$ibp_location.*"
505    gdb_test "python print (ibp.count)" "1" \
506	"Check temporary stop callback executed before deletion."
507    gdb_test "python print (ibp.temporary)" "RuntimeError: Breakpoint 2 is invalid.*" \
508	"Check temporary breakpoint is deleted after being hit"
509    gdb_test "info breakpoints" "No breakpoints or watchpoints.*" \
510	"Check info breakpoints shows temporary breakpoint is deleted"
511}
512
513# Test address locations.
514
515proc_with_prefix test_bkpt_address {} {
516    global gdb_prompt decimal srcfile
517
518    # Delete all breakpoints
519    delete_breakpoints
520
521    gdb_test "python gdb.Breakpoint(\"*main\")" \
522	".*Breakpoint ($decimal)+ at .*$srcfile, line ($decimal)+\."
523
524    gdb_py_test_silent_cmd \
525	"python main_loc = gdb.parse_and_eval(\"main\").address" \
526	"eval address of main" 0
527
528    # Python 2 vs 3 ... Check `int' first. If that fails, try `long'.
529    gdb_test_multiple "python main_addr = int(main_loc)" "int value of main" {
530	-re "Traceback.*$gdb_prompt $" {
531	    gdb_test_no_output "python main_addr = long(main_loc)" \
532		"long value of main"
533	}
534	-re "$gdb_prompt $" {
535	    pass "int value of main"
536	}
537    }
538
539    # Include whitespace in the linespec to double-check proper
540    # grokking of argument to gdb.Breakpoint.
541    gdb_test "python gdb.Breakpoint(\"  *{}\".format(str(main_addr)))" \
542	".*Breakpoint ($decimal)+ at .*$srcfile, line ($decimal)+\."
543}
544
545proc_with_prefix test_bkpt_pending {} {
546    delete_breakpoints
547    gdb_breakpoint "nosuchfunction" allow-pending
548    gdb_test "python print (gdb.breakpoints()\[0\].pending)" "True" \
549	"Check pending status of pending breakpoint"
550}
551
552# Helper proc to install an event listener for a given breakpoint
553# event.  NAME is the name of the event to listen for.
554proc connect_event {name} {
555    set lambda "lambda x: note_event(\"$name\")"
556    gdb_test_no_output "python gdb.events.$name.connect($lambda)" \
557	"install $name event listener"
558}
559
560# Helper proc to check that the most recently emitted breakpoint event
561# is EXPECTED.
562proc check_last_event {expected} {
563    gdb_test "python print (last_bp_event)" $expected \
564	"check for $expected event"
565}
566
567proc_with_prefix test_bkpt_events {} {
568    global testfile
569
570    clean_restart ${testfile}
571
572    gdb_test_multiline "Create event handler" \
573	"python" "" \
574	"def note_event(arg):" "" \
575	"  global last_bp_event" "" \
576	"  last_bp_event = arg" "" \
577	"end" ""
578    gdb_test_no_output "python last_bp_event = None"
579
580    connect_event breakpoint_created
581    connect_event breakpoint_modified
582    connect_event breakpoint_deleted
583
584    gdb_breakpoint [gdb_get_line_number "Break at add."]
585    check_last_event breakpoint_created
586    gdb_test_no_output "disable 1"
587    check_last_event breakpoint_modified
588    gdb_test_no_output "delete 1"
589    check_last_event breakpoint_deleted
590}
591
592proc_with_prefix test_bkpt_explicit_loc {} {
593    global srcfile testfile
594
595    # Start with a fresh gdb.
596    clean_restart ${testfile}
597
598    if {![runto_main]} {
599	return 0
600    }
601
602    delete_breakpoints
603
604    set bp_location1 [gdb_get_line_number "Break at multiply."]
605    set bp_location2 [gdb_get_line_number "Break at add."]
606
607    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (line=$bp_location1)" \
608	"set explicit breakpoint by line" 0
609    gdb_continue_to_breakpoint "break at multiply for explicit line" \
610	".*Break at multiply.*"
611
612    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (line=\"+1\")" \
613	"set explicit breakpoint by relative line" 0
614    gdb_continue_to_breakpoint "break at add for relative line" \
615	".*Break at add.*"
616
617    delete_breakpoints
618    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (line=\"-1\")" \
619	"set explicit breakpoint by relative negative line" 0
620    gdb_continue_to_breakpoint "break at multiply for negative line" \
621	".*Break at multiply.*"
622
623    delete_breakpoints
624    gdb_test "python bp1 = gdb.Breakpoint (line=bp1)" \
625	"RuntimeError: Line keyword should be an integer or a string.*" \
626	"set explicit breakpoint by invalid line type"
627
628    delete_breakpoints
629    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (function=\"add\")" \
630	"set explicit breakpoint by function" 0
631    gdb_continue_to_breakpoint "break at function add for function" \
632	".*Break at function add.*"
633
634    delete_breakpoints
635    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (source=\"$srcfile\", function=\"add\")" \
636	"set explicit breakpoint by source file and function" 0
637    gdb_continue_to_breakpoint "break at function add for source and function" \
638	".*Break at function add.*"
639
640    delete_breakpoints
641    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (source=\"$srcfile\", line=\"$bp_location2\")" \
642	"set explicit breakpoint by source file and line number" 0
643    gdb_continue_to_breakpoint "break at add for source and line" \
644	".*Break at add.*"
645
646    delete_breakpoints
647    gdb_py_test_silent_cmd "python bp1 = gdb.Breakpoint (\"-source $srcfile -line $bp_location2\")" \
648	"set explicit breakpoint by source file and line number in spec" 0
649    gdb_continue_to_breakpoint "break at add for source and line in spec" \
650	".*Break at add.*"
651
652    delete_breakpoints
653    gdb_test "python bp1 = gdb.Breakpoint (source=\"$srcfile\")" \
654	"RuntimeError: Specifying a source must also include a line, label or function.*" \
655	"set invalid explicit breakpoint by source only"
656
657    gdb_test "python bp1 = gdb.Breakpoint (source=\"foo.c\", line=\"5\")" \
658	"No source file named foo.*" \
659	"set invalid explicit breakpoint by missing source and line"
660    gdb_test "python bp1 = gdb.Breakpoint (source=\"$srcfile\", line=\"900\")" \
661	"No line 900 in file \"$srcfile\".*" \
662	"set invalid explicit breakpoint by source and invalid line"
663    gdb_test "python bp1 = gdb.Breakpoint (function=\"blah\")" \
664	"Function \"blah\" not defined.*" \
665	"set invalid explicit breakpoint by missing function"
666
667    delete_breakpoints
668    gdb_test "catch throw" "Catchpoint .* \\(throw\\)"
669    gdb_test "python print (gdb.breakpoints())" \
670	"\(\)" \
671	"catch throw is not a breakpoint"
672}
673
674proc_with_prefix test_bkpt_qualified {} {
675    global decimal hex testfile
676
677    # Start with a fresh gdb.
678    clean_restart ${testfile}
679
680    set one_location_re "Breakpoint $decimal at $hex:.*line $decimal."
681    set two_location_re "Breakpoint $decimal at $hex:.*2 locations."
682
683    if {![runto_main]} {
684	return 0
685    }
686
687    # Test the default value of "qualified".
688    delete_breakpoints
689    gdb_test \
690	"python gdb.Breakpoint(\"multiply\")" \
691	$two_location_re \
692	"qualified implicitly false"
693
694    # Test qualified=False.
695    delete_breakpoints
696    gdb_test \
697	"python gdb.Breakpoint(\"multiply\", qualified=False)" \
698	$two_location_re \
699	"qualified false"
700
701    # Test qualified=True.
702    delete_breakpoints
703    gdb_test \
704	"python gdb.Breakpoint(\"multiply\", qualified=True)" \
705	$one_location_re \
706	"qualified true"
707
708    # Test qualified=True with an explicit function.
709    delete_breakpoints
710    gdb_test \
711	"python gdb.Breakpoint(function=\"multiply\", qualified=True)" \
712	$one_location_re \
713	"qualified true and explicit"
714
715    # Test qualified=False with an explicit function.
716    delete_breakpoints
717    gdb_test \
718	"python gdb.Breakpoint(function=\"multiply\", qualified=False)" \
719	$two_location_re \
720	"qualified false and explicit"
721
722    # Test -q in the spec string.
723    delete_breakpoints
724    gdb_test \
725	"python gdb.Breakpoint(\"-q multiply\")" \
726	$one_location_re \
727	"-q in spec string"
728
729    # Test -q in the spec string with explicit location.
730    delete_breakpoints
731    gdb_test \
732	"python gdb.Breakpoint(\"-q -function multiply\")" \
733	$one_location_re \
734	"-q in spec string with explicit location"
735
736    # Test -q in the spec string and qualified=False (-q should win).
737    delete_breakpoints
738    gdb_test \
739	"python gdb.Breakpoint(\"-q multiply\", qualified=False)" \
740	$one_location_re \
741	"-q in spec string and qualified false"
742}
743
744proc_with_prefix test_bkpt_probe {} {
745    global decimal hex testfile srcfile
746
747    if { [prepare_for_testing "failed to prepare" ${testfile}-probes \
748	    ${srcfile} {debug c++ additional_flags=-DUSE_PROBES}] } {
749	return -1
750    }
751
752    if {![runto_main]} {
753	return 0
754    }
755
756    gdb_test \
757	"python gdb.Breakpoint(\"-probe test:result_updated\")" \
758	"Breakpoint $decimal at $hex" \
759	"-probe in spec string"
760}
761
762proc_with_prefix test_catchpoints {} {
763    global srcfile testfile
764    global gdb_prompt decimal
765
766    # Start with a fresh gdb.
767    clean_restart ${testfile}
768
769    if {![runto_main]} {
770	return 0
771    }
772
773    # Try to create a catchpoint, currently this isn't supported via
774    # the python api.
775    gdb_test "python gdb.Breakpoint (\"syscall\", type=gdb.BP_CATCHPOINT)" \
776	[multi_line \
777	     "gdb.error: BP_CATCHPOINT not supported" \
778	     "Error while executing Python code\\."] \
779	"create a catchpoint via the api"
780
781    # Setup a catchpoint.
782    set num "XXX"
783    gdb_test_multiple "catch throw" "" {
784	-re "The feature \'catch throw\' is not supported.*\r\n$gdb_prompt $" {
785	    unsupported "catch syscall isn't supported"
786	    return -1
787	}
788	-re "Catchpoint ($decimal) \\(throw\\)\r\n$gdb_prompt $" {
789	    set num $expect_out(1,string)
790	    pass $gdb_test_name
791	}
792    }
793
794    # Look for the catchpoint in the breakpoint list.
795    gdb_test_multiline "scan breakpoint list for BP_CATCHPOINT" \
796	"python" "" \
797	"def scan_bp_list ():" "" \
798	"  for b in gdb.breakpoints():" "" \
799	"    if b.type == gdb.BP_CATCHPOINT:" "" \
800	"      print(\"breakpoint #%d, type BP_CATCHPOINT\" % b.number)" "" \
801	"end" ""
802    gdb_test "python scan_bp_list ()" \
803	"breakpoint #${num}, type BP_CATCHPOINT" \
804	"scan breakpoint for BP_CATCHPOINT"
805
806    # Arrange to print something when GDB stops, then continue to the
807    # catchpoint and check we get the expected event.
808    gdb_test_multiline "setup stop event handler" \
809	"python" "" \
810	"def stop_handler (event):" "" \
811	"  if (isinstance (event, gdb.BreakpointEvent)" "" \
812	"      and isinstance (event.breakpoint, gdb.Breakpoint)" "" \
813	"      and event.breakpoint.type == gdb.BP_CATCHPOINT):" "" \
814	"    print (\"Stopped at catchpoint event: %d\" % event.breakpoint.number)" "" \
815	"end" "" \
816	"python gdb.events.stop.connect (stop_handler)" ""
817    gdb_test "continue" "Stopped at catchpoint event: ${num}"
818}
819
820# Test auto-disable is effective when notifying breakpoint_modified.
821
822proc_with_prefix test_bkpt_auto_disable { } {
823    global srcfile testfile hex decimal
824
825    # Start with a fresh gdb.
826    clean_restart ${testfile}
827
828    if {![runto_main]} {
829	return 0
830    }
831    delete_breakpoints
832
833    set mult_line [gdb_get_line_number "Break at multiply."]
834    gdb_breakpoint ${mult_line}
835    gdb_test_no_output "enable count 1 2" "one shot enable"
836    # Python 2 doesn't support print in lambda function, so use a named
837    # function instead.
838    gdb_test_multiline "Define print_bp_enabled" \
839	"python" "" \
840	"def print_bp_enabled (bp):" "" \
841	"    print (bp.enabled)" "" \
842	"end" ""
843    gdb_test_no_output \
844	"python gdb.events.breakpoint_modified.connect(print_bp_enabled)" \
845	"trap breakpoint_modified event"
846    gdb_test "continue" "False.*" "auto-disabling after enable count reached"
847}
848
849test_bkpt_basic
850test_bkpt_deletion
851test_bkpt_cond_and_cmds
852test_bkpt_invisible
853test_hardware_breakpoints
854test_catchpoints
855test_watchpoints
856test_bkpt_internal
857test_bkpt_eval_funcs
858test_bkpt_temporary
859test_bkpt_address
860test_bkpt_pending
861test_bkpt_events
862test_bkpt_explicit_loc
863test_bkpt_qualified
864test_bkpt_probe
865test_bkpt_auto_disable
866