From: Pedro Alves Date: Mon, 16 May 2022 11:48:51 +0000 (+0100) Subject: Test "set multiple-symbols on" creating multiple breakpoints X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=46f0aab14350e9e380c6bbe7bf0539932241fb5b;p=binutils-gdb.git Test "set multiple-symbols on" creating multiple breakpoints To look for code paths that lead to create_breakpoints_sal creating multiple breakpoints, I ran the whole testsuite with this hack: --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -8377,8 +8377,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch, int from_tty, int enabled, int internal, unsigned flags) { - if (canonical->pre_expanded) - gdb_assert (canonical->lsals.size () == 1); + gdb_assert (canonical->lsals.size () == 1); surprisingly, the assert never failed... The way to get to create_breakpoints_sal with multiple lsals is to use "set multiple-symbols ask" and then select multiple options from the menu, like so: (gdb) set multiple-symbols ask (gdb) b overload1arg [0] cancel [1] all [2] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg() [3] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(char) [4] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(double) [5] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(float) [6] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(int) [7] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(long) [8] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(short) [9] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(signed char) [10] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(unsigned char) [11] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(unsigned int) [12] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(unsigned long) [13] /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc:foo::overload1arg(unsigned short) > 2-3 Breakpoint 2 at 0x1532: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc, line 107. Breakpoint 3 at 0x154b: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.cp/ovldbreak.cc, line 110. warning: Multiple breakpoints were set. Use the "delete" command to delete unwanted breakpoints. ... which would trigger the assert. This commit makes gdb.cp/ovldbreak.exp test this scenario. It does that by making set_bp_overloaded take a list of expected created breakpoints rather than just one breakpoint. It converts the procedure to use gdb_test_multiple instead of send_gdb/gdb_expect along the way. Change-Id: Id87d1e08feb6670440d926f5344e5081f5e37c8e --- diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp index 681edf204d3..06adf82ecbb 100644 --- a/gdb/testsuite/gdb.cp/ovldbreak.exp +++ b/gdb/testsuite/gdb.cp/ovldbreak.exp @@ -67,43 +67,75 @@ proc take_gdb_out_of_choice_menu {} { -# This procedure sets an overloaded breakpoint. -# When I ask for such a breakpoint, gdb gives me a menu of 'cancel' 'all' -# and a bunch of choices. I then choose from that menu by number. +# This procedure sets an overloaded breakpoint. When users ask for +# such a breakpoint, gdb gives a menu of 'cancel' 'all' and one choice +# per overload. Users can then choose from that menu by number. +# +# NAME is the spec to use to create the breakpoint. EXPECTEDMENU is +# the expected menu. MYCHOICE is the choice selected. Can be more +# than one overload, e.g. "2-3". BPNUMBER is the expected next +# breakpoint created. LINENUMBERS is a list of line numbers, one +# element per expected breakpoint created. -proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} { - global gdb_prompt hex srcfile +proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumbers} { + global gdb_prompt hex decimal srcfile # Get into the overload menu. - send_gdb "break $name\n" - gdb_expect { - -re "$expectedmenu" { - pass "bp menu for $name choice $mychoice" - - # Choose my choice. - send_gdb "$mychoice\n" - gdb_expect { - -re "Breakpoint $bpnumber at $hex: file.*$srcfile, line $linenumber.\r\n$gdb_prompt $" { - pass "set bp $bpnumber on $name $mychoice line $linenumber" - } - -re ".*$gdb_prompt $" { - fail "set bp $bpnumber on $name $mychoice line $linenumber (bad bp)" + gdb_test_multiple "break $name" "bp menu for $name choice $mychoice" { + -re "$expectedmenu" { + pass $gdb_test_name + + set any "\[^\r\n\]*" + + # True if we've seen a bad breakpoint. + set bad_bp 0 + + # How many breakpoints we expect to see. + set expected_bps [llength $linenumbers] + + # The count of seen breakpoints. + set seen_bps 0 + + # Choose my choice. + gdb_test_multiple "$mychoice" "set bp $bpnumber on $name $mychoice line $linenumbers" { + -re "Breakpoint ($decimal) at $hex: file$any$srcfile, line ($decimal).\r\n" { + + set got_num $expect_out(1,string) + set got_line $expect_out(2,string) + + if {$seen_bps >= $expected_bps} { + set bad_bp 1 + } else { + set linenumber [lindex $linenumbers $seen_bps] + + if {$got_num != $bpnumber || $got_line != $linenumber} { + set bad_bp 1 + } + + incr bpnumber + incr seen_bps + } + exp_continue + } + -re "$gdb_prompt $" { + gdb_assert {!$bad_bp && $seen_bps == $expected_bps} \ + $gdb_test_name } timeout { - fail "set bp $bpnumber on $name $mychoice line $linenumber (timeout)" + fail "$gdb_test_name (timeout)" take_gdb_out_of_choice_menu } } } -re ".*\r\n> " { - fail "bp menu for $name choice $mychoice (bad menu)" + fail "$gdb_test_name (bad menu)" take_gdb_out_of_choice_menu } -re ".*$gdb_prompt $" { - fail "bp menu for $name choice $mychoice (no menu)" + fail "$gdb_test_name (no menu)" } timeout { - fail "bp menu for $name choice $mychoice (timeout)" + fail "$gdb_test_name (timeout)" take_gdb_out_of_choice_menu } } @@ -198,8 +230,10 @@ append menu_overload1arg {[\r\n]*> $} # of the multiple-choice menu when breaking on an overloaded method. gdb_test_no_output "set multiple-symbols ask" -# Set breakpoints on foo::overload1arg, one by one. +# The last breakpoint created. set bpnum 1 + +# Set breakpoints on foo::overload1arg, one by one. set method "foo::overload1arg" for {set idx 0} {$idx < [llength $overloads]} {incr idx} { set type [lindex $overloads $idx] @@ -257,6 +291,21 @@ gdb_expect { gdb_test "info break" $bptable "breakpoint info (after cancel)" +# Test that if the user selects multiple entries from the option list, +# GDB creates one breakpoint per entry. +with_test_prefix "multiple breakpoints" { + set method "foo::overload1arg" + + set expected_lines {} + for {set i 0} {$i < 2} {incr i} { + set type [lindex $overloads $i] + lappend expected_lines $line($type_map("$type")) + } + set_bp_overloaded $method $menu_overload1arg \ + "2-3" [incr bpnum] $expected_lines + incr bpnum +} + # Delete these breakpoints. send_gdb "delete breakpoints\n" @@ -284,6 +333,7 @@ gdb_test "info breakpoints" "No breakpoints or watchpoints." "breakpoint info (a # Test choice "all". # This is copy-and-paste from set_bp_overloaded. +incr bpnum send_gdb "break foo::overload1arg\n" gdb_expect { -re "$menu_overload1arg" { @@ -291,7 +341,7 @@ gdb_expect { # Choose all. send_gdb "1\n" gdb_expect { - -re "Breakpoint $decimal at $hex: foo::overload1arg. .12 locations.\r\n.*$gdb_prompt $" { + -re "Breakpoint $bpnum at $hex: foo::overload1arg. .12 locations.\r\n.*$gdb_prompt $" { pass "set bp on overload1arg all" } -re ".*$gdb_prompt $" { @@ -380,7 +430,7 @@ array set might_fail { } foreach type $all_types { - continue_to_bp_overloaded 14 $might_fail($type) $line($type) \ + continue_to_bp_overloaded $bpnum $might_fail($type) $line($type) \ $type $arguments($type) }