1# Copyright (C) 1998-2020 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# written by Elena Zannoni (ezannoni@cygnus.com) 17# modified by Michael Chastain (chastain@redhat.com) 18 19# This file is part of the gdb testsuite 20# 21# tests for overloaded member functions. Set breakpoints on 22# overloaded member functions 23# 24 25global timeout 26set timeout 15 27# 28# test running programs 29# 30 31if { [skip_cplus_tests] } { continue } 32 33standard_testfile .cc 34 35if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { 36 return -1 37} 38 39# set it up at a breakpoint so we can play with the variable values 40# 41if {![runto_main]} { 42 perror "couldn't run to breakpoint" 43 continue 44} 45 46# When I ask gdb to set a breakpoint on an overloaded function, 47# gdb gives me a choice menu. I might get stuck in that choice menu 48# (for example, if C++ name mangling is not working properly). 49# 50# This procedure issues a command that works at either the menu 51# prompt or the command prompt to get back to the command prompt. 52# 53# Note that an empty line won't do it (it means 'repeat the previous command' 54# at top level). A line with a single space in it works nicely. 55 56proc take_gdb_out_of_choice_menu {} { 57 global gdb_prompt 58 gdb_test_multiple " " " " { 59 -re ".*$gdb_prompt $" { 60 } 61 timeout { 62 perror "could not resynchronize to command prompt (timeout)" 63 continue 64 } 65 } 66} 67 68 69 70# This procedure sets an overloaded breakpoint. 71# When I ask for such a breakpoint, gdb gives me a menu of 'cancel' 'all' 72# and a bunch of choices. I then choose from that menu by number. 73 74proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} { 75 global gdb_prompt hex srcfile 76 77 # Get into the overload menu. 78 send_gdb "break $name\n" 79 gdb_expect { 80 -re "$expectedmenu" { 81 pass "bp menu for $name choice $mychoice" 82 83 # Choose my choice. 84 send_gdb "$mychoice\n" 85 gdb_expect { 86 -re "Breakpoint $bpnumber at $hex: file.*$srcfile, line $linenumber.\r\n$gdb_prompt $" { 87 pass "set bp $bpnumber on $name $mychoice line $linenumber" 88 } 89 -re ".*$gdb_prompt $" { 90 fail "set bp $bpnumber on $name $mychoice line $linenumber (bad bp)" 91 } 92 timeout { 93 fail "set bp $bpnumber on $name $mychoice line $linenumber (timeout)" 94 take_gdb_out_of_choice_menu 95 } 96 } 97 } 98 -re ".*\r\n> " { 99 fail "bp menu for $name choice $mychoice (bad menu)" 100 take_gdb_out_of_choice_menu 101 } 102 -re ".*$gdb_prompt $" { 103 fail "bp menu for $name choice $mychoice (no menu)" 104 } 105 timeout { 106 fail "bp menu for $name choice $mychoice (timeout)" 107 take_gdb_out_of_choice_menu 108 } 109 } 110} 111 112# Compute the expected menu for overload1arg. 113# Note the arg type variations for void and integer types. 114# This accommodates different versions of g++. 115 116# Probe for the real types. This will do some unnecessary checking 117# for some simple types (like "int"), but it's just easier to loop 118# over all_types instead of calling out just the exceptions. 119# This list /must/ remain in the same order that the methods are 120# called in the source code. Otherwise the order in which breakpoints 121# are hit (tested below) will be incorrect. 122set all_types [list void char signed_char unsigned_char short_int \ 123 unsigned_short_int int unsigned_int long_int \ 124 unsigned_long_int float double] 125 126# ARGUMENTS is an array that will map from synthetic type to argument 127# expressions in the source code, which is of the form "arg = $decimal". 128# ARGUMENTS stores this decimal number. 129array set arguments { 130 void "" 131 char 2 132 signed_char 3 133 unsigned_char 4 134 short_int 5 135 unsigned_short_int 6 136 int 7 137 unsigned_int 8 138 long_int 9 139 unsigned_long_int 10 140 float 100(.0)? 141 double 200(.0)? 142} 143 144unset -nocomplain line types 145foreach type $all_types { 146 # TYPES is an array that maps the synthetic names in ALL_TYPES 147 # to the real type used in the debugger. These will be checked 148 # below and changed if the debugger thinks they are different from 149 # their default values. 150 set types($type) [join [split $type "_"] " "] 151 152 # LINE is an array that will map from synthetic type to line number. 153 # in the source code. 154 set line($type) [gdb_get_line_number "fo1 $type"] 155 156 # Probe for the actual type. 157 gdb_test_multiple "print &foo::overload1arg($types($type))" \ 158 "probe $types($type)" { 159 -re ".*\<foo::.*\>.*$gdb_prompt $" { 160 regexp {<.*>} $expect_out(0,string) func 161 regexp {\(.*\)} $func real_type 162 163 # Store the real type into TYPES. 164 set types($type) [string trim $real_type {()}] 165 166 # Create an inverse mapping of the actual type to 167 # the synthetic type. 168 set type_map("$types($type)") $type 169 pass "detect $type" 170 } 171 } 172} 173 174# This is a list of the actual overloaded method arguments. 175set overloads {} 176foreach type $all_types { 177 lappend overloads $types($type) 178} 179 180# Sort this list alphabetically. 181set overloads [lsort $overloads] 182 183# Create the menu list. 184set items {"cancel" "all"} 185foreach ovld $overloads { 186 lappend items "$srcfile:foo::overload1arg\\($ovld\\)" 187} 188set menu_items {} 189set idx 0 190foreach item $items { 191 lappend menu_items ".$idx. .*$item" 192 incr idx 193} 194set menu_overload1arg [join $menu_items {[\r\n]*}] 195append menu_overload1arg {[\r\n]*> $} 196 197# Set multiple-symbols to "ask", to allow us to test the use 198# of the multiple-choice menu when breaking on an overloaded method. 199gdb_test_no_output "set multiple-symbols ask" 200 201# Set breakpoints on foo::overload1arg, one by one. 202set bpnum 1 203set method "foo::overload1arg" 204for {set idx 0} {$idx < [llength $overloads]} {incr idx} { 205 set type [lindex $overloads $idx] 206 set_bp_overloaded $method $menu_overload1arg \ 207 [expr {$idx + 2}] [incr bpnum] $line($type_map("$type")) 208} 209 210# Verify the breakpoints. 211set bptable "Num\[\t \]+Type\[\t \]+Disp Enb Address\[\t \]+What.*\[\r\n]+" 212append bptable "\[0-9\]+\[\t \]+breakpoint\[\t \]+keep\[\t \]y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\[\r\n\]+" 213append bptable "\[\t \]+breakpoint already hit 1 time\[\r\n\]+." 214foreach ovld $overloads { 215 append bptable [format "\[0-9\]+\[\t \]+breakpoint\[\t \]+keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(%s\\) at.*$srcfile:%d\[\r\n\]+" $ovld \ 216 $line($type_map("$ovld"))] 217} 218gdb_test "info break" $bptable "breakpoint info (after setting one-by-one)" 219 220# Test choice "cancel". 221# This is copy-and-paste from set_bp_overloaded. 222 223send_gdb "break foo::overload1arg\n" 224gdb_expect { 225 -re "$menu_overload1arg" { 226 pass "bp menu for foo::overload1arg choice cancel" 227 # Choose cancel. 228 send_gdb "0\n" 229 gdb_expect { 230 -re "canceled\r\n$gdb_prompt $" { 231 pass "set bp on overload1arg canceled" 232 } 233 -re "cancelled\r\n$gdb_prompt $" { 234 pass "set bp on overload1arg canceled" 235 } 236 -re ".*$gdb_prompt $" { 237 fail "set bp on overload1arg canceled (bad message)" 238 } 239 timeout { 240 fail "set bp on overload1arg canceled (timeout)" 241 take_gdb_out_of_choice_menu 242 } 243 } 244 } 245 -re ".*\r\n> " { 246 fail "bp menu for foo::overload1arg choice cancel (bad menu)" 247 take_gdb_out_of_choice_menu 248 } 249 -re ".*$gdb_prompt $" { 250 fail "bp menu for foo::overload1arg choice cancel (no menu)" 251 } 252 timeout { 253 fail "bp menu for foo::overload1arg choice cancel (timeout)" 254 take_gdb_out_of_choice_menu 255 } 256} 257 258gdb_test "info break" $bptable "breakpoint info (after cancel)" 259 260# Delete these breakpoints. 261 262send_gdb "delete breakpoints\n" 263gdb_expect { 264 -re "Delete all breakpoints.* $" { 265 send_gdb "y\n" 266 gdb_expect { 267 -re ".*$gdb_prompt $" { 268 pass "delete all breakpoints" 269 } 270 timeout { 271 fail "delete all breakpoints (timeout)" 272 } 273 } 274 } 275 timeout { 276 fail "delete all breakpoints (timeout)" 277 } 278} 279 280gdb_test "info breakpoints" "No breakpoints or watchpoints." "breakpoint info (after delete)" 281 282 283 284# Test choice "all". 285# This is copy-and-paste from set_bp_overloaded. 286 287send_gdb "break foo::overload1arg\n" 288gdb_expect { 289 -re "$menu_overload1arg" { 290 pass "bp menu for foo::overload1arg choice all" 291 # Choose all. 292 send_gdb "1\n" 293 gdb_expect { 294 -re "Breakpoint $decimal at $hex: foo::overload1arg. .12 locations.\r\n.*$gdb_prompt $" { 295 pass "set bp on overload1arg all" 296 } 297 -re ".*$gdb_prompt $" { 298 fail "set bp on overload1arg all (bad message)" 299 } 300 timeout { 301 fail "set bp on overload1arg all (timeout)" 302 take_gdb_out_of_choice_menu 303 } 304 } 305 } 306 -re ".*\r\n> " { 307 fail "bp menu for foo::overload1arg choice all (bad menu)" 308 take_gdb_out_of_choice_menu 309 } 310 -re ".*$gdb_prompt $" { 311 fail "bp menu for foo::overload1arg choice all (no menu)" 312 } 313 timeout { 314 fail "bp menu for foo::overload1arg choice all (timeout)" 315 take_gdb_out_of_choice_menu 316 } 317} 318 319# Create the breakpoint table for "info breakpoint". 320set bptable "Num\[\t \]+Type\[\t \]+Disp Enb Address\[\t \]+What.*\[\r\n]+" 321append bptable "\[0-9\]+\[\t \]+breakpoint\[\t \]+keep\[\t \]y\[\t \]+<MULTIPLE>.*\[\r\n\]+" 322foreach ovld {void char signed_char unsigned_char short_int \ 323 unsigned_short_int int unsigned_int long_int \ 324 unsigned_long_int float double} { 325 append bptable [format "\[0-9\]+.\[0-9\]+\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(%s\\) at.*$srcfile:%d\[\r\n\]+" \ 326 $types($ovld) $line($ovld)] 327} 328 329gdb_test "info break" $bptable "breakpoint info (after setting on all)" 330 331# Run through each breakpoint. 332proc continue_to_bp_overloaded {bpnumber might_fail line argtype argument} { 333 global gdb_prompt hex decimal srcfile 334 335 if {$argument == ""} { 336 set actuals "" 337 } else { 338 set actuals "arg=$argument" 339 if {[regexp {char} $argtype]} { 340 append actuals " \\'\\\\00$argument\\'" 341 } 342 } 343 344 if {[string match $argtype "void"]} { 345 set body "return $decimal;" 346 } else { 347 set body "arg = 0; return $decimal;" 348 } 349 350 gdb_test_multiple "continue" "continue to bp overloaded : $argtype" { 351 -re "Continuing.\r\n\r\nBreakpoint $bpnumber, foo::overload1arg \\(this=${hex}(, )?$actuals\\) at .*$srcfile:$line\r\n$decimal\[\t \]+{ $body }.*$gdb_prompt $" { 352 pass "continue to bp overloaded : $argtype" 353 } 354 355 -re "Continuing.\r\n\r\nBreakpoint $bpnumber, foo::overload1arg \\(this=${hex}, arg=.*\\) at .*$srcfile:$line\r\n$decimal\[\t \]+{ $body }.*$gdb_prompt $" { 356 if $might_kfail { 357 kfail "c++/8130" "continue to bp overloaded : $argtype" 358 } else { 359 fail "continue to bp overloaded : $argtype" 360 } 361 } 362 } 363} 364 365# An array which describes which of these methods might be expected 366# to kfail on GCC 2.95. See C++/8210. 367array set might_fail { 368 void 0 369 char 1 370 signed_char 1 371 unsigned_char 1 372 short_int 1 373 unsigned_short_int 1 374 int 0 375 unsigned_int 0 376 long_int 0 377 unsigned_long_int 0 378 float 0 379 double 1 380} 381 382foreach type $all_types { 383 continue_to_bp_overloaded 14 $might_fail($type) $line($type) \ 384 $type $arguments($type) 385} 386 387# Test breaking on an overloaded function when multiple-symbols 388# is set to "cancel" 389gdb_test_no_output "set multiple-symbols cancel" 390gdb_test "break foo::foofunc" \ 391 "canceled.*" 392 393# Test breaking on an overloaded function when multiple-symbols 394# is set to "all" 395gdb_test_no_output "set multiple-symbols all" 396gdb_test "break foo::foofunc" \ 397 "Breakpoint \[0-9\]+ at ${hex}: foo::foofunc. .2 locations..*" 398 399# That's all, folks. 400 401unset -nocomplain line types 402gdb_continue_to_end "finish program" 403