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