1# Copyright 2000-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# This file is based on config/gdbserver.exp, which was written by 17# Michael Snyder (msnyder@redhat.com). 18 19# 20# To be addressed or set in your baseboard config file: 21# 22# set_board_info gdb_protocol "remote" 23# Unles you have a gdbserver that uses a different protocol... 24# After GDB starts you should check global $gdbserver_protocol instead as 25# the testfile may force a specific different target protocol itself. 26# 27# set_board_info gdb_server_prog 28# This will be the path to the gdbserver program you want to test. 29# Defaults to "gdbserver". 30# 31# set_board_info sockethost 32# The name of the host computer whose socket is being used. 33# Defaults to "localhost". Note: old gdbserver requires 34# that you define this, but libremote/gdbserver does not. 35# 36# set_board_info gdb,socketport 37# Port id to use for socket connection. If not set explicitly, 38# it will start at "2345" and increment for each use. 39# After GDB starts you should check global $gdbserver_gdbport for the 40# real port used. It is not useful if $gdbserver_reconnect_p was not set. 41# 42 43# 44# gdb_target_cmd 45# Send gdb the "target" command 46# 47proc gdb_target_cmd { targetname serialport } { 48 global gdb_prompt 49 50 set serialport_re [string_to_regexp $serialport] 51 for {set i 1} {$i <= 3} {incr i} { 52 send_gdb "target $targetname $serialport\n" 53 gdb_expect 60 { 54 -re "A program is being debugged already.*ill it.*y or n. $" { 55 send_gdb "y\n" 56 exp_continue 57 } 58 -re "unknown host.*$gdb_prompt" { 59 verbose "Couldn't look up $serialport" 60 } 61 -re "Couldn't establish connection to remote.*$gdb_prompt $" { 62 verbose "Connection failed" 63 } 64 -re "Remote MIPS debugging.*$gdb_prompt" { 65 verbose "Set target to $targetname" 66 return 0 67 } 68 -re "Remote debugging using .*$serialport_re.*$gdb_prompt $" { 69 verbose "Set target to $targetname" 70 return 0 71 } 72 -re "Remote debugging using stdio.*$gdb_prompt $" { 73 verbose "Set target to $targetname" 74 return 0 75 } 76 -re "Remote target $targetname connected to.*$gdb_prompt $" { 77 verbose "Set target to $targetname" 78 return 0 79 } 80 -re "Connected to.*$gdb_prompt $" { 81 verbose "Set target to $targetname" 82 return 0 83 } 84 -re "Ending remote.*$gdb_prompt $" { } 85 -re "Connection refused.*$gdb_prompt $" { 86 verbose "Connection refused by remote target. Pausing, and trying again." 87 sleep 30 88 continue 89 } 90 -re "Timeout reading from remote system.*$gdb_prompt $" { 91 verbose "Got timeout error from gdb." 92 } 93 -notransfer -re "Remote debugging using .*\r\n> $" { 94 # We got an unexpected prompt while creating the target. 95 # Leave it there for the test to diagnose. 96 return 1 97 } 98 timeout { 99 send_gdb "" 100 break 101 } 102 } 103 } 104 return 1 105} 106 107 108global portnum 109set portnum "2345" 110 111# Locate the gdbserver binary. Returns "" if gdbserver could not be found. 112 113proc find_gdbserver { } { 114 global GDB 115 global GDBSERVER 116 117 if [info exists GDBSERVER] { 118 return ${GDBSERVER} 119 } 120 121 if [target_info exists gdb_server_prog] { 122 return [target_info gdb_server_prog] 123 } 124 125 set gdbserver "${GDB}server" 126 if { [file isdirectory $gdbserver] } { 127 append gdbserver "/gdbserver" 128 } 129 130 if { [file executable $gdbserver] } { 131 return $gdbserver 132 } 133 134 return "" 135} 136 137# Return non-zero if we should skip gdbserver-specific tests. 138 139proc skip_gdbserver_tests { } { 140 if { [find_gdbserver] == "" } { 141 return 1 142 } 143 144 # If GDB is lack of XML support, and targets, like arm, have 145 # multiple target descriptions, GDB doesn't know which target 146 # description GDBserver uses, and may fail to parse 'g' packet 147 # after connection. 148 if { [gdb_skip_xml_test] 149 && ([istarget "arm*-*-linux*"] 150 || [istarget "mips*-*-linux*"] 151 || [istarget "powerpc*-*-linux*"] 152 || [istarget "s390*-*-linux*"] 153 || [istarget "x86_64-*-linux*"] 154 || [istarget "i\[34567\]86-*-linux*"]) } { 155 return 1 156 } 157 158 return 0 159} 160 161# Download the currently loaded program to the target if necessary. 162# Return the target system filename. 163# NOTE: This was named "gdbserver_download", but that collides with the 164# dejagnu "download" API function when using load_generic_config "gdbserver". 165 166proc gdbserver_download_current_prog { } { 167 global gdbserver_host_exec 168 global gdbserver_host_mtime 169 global gdbserver_server_exec 170 global last_loaded_file 171 172 if { ![info exists last_loaded_file] } { 173 return "" 174 } 175 176 set host_exec $last_loaded_file 177 178 # If we already downloaded a file to the target, see if we can reuse it. 179 set reuse 0 180 if { [info exists gdbserver_server_exec] } { 181 set reuse 1 182 183 # If the file has changed, we can not. 184 if { $host_exec != $gdbserver_host_exec } { 185 set reuse 0 186 } 187 188 # If the mtime has changed, we can not. 189 if { [file mtime $host_exec] != $gdbserver_host_mtime } { 190 set reuse 0 191 } 192 } 193 194 if { $reuse == 0 } { 195 set gdbserver_host_exec $host_exec 196 set gdbserver_host_mtime [file mtime $host_exec] 197 set gdbserver_server_exec [gdb_remote_download target $host_exec] 198 } 199 200 return $gdbserver_server_exec 201} 202 203# Default routine to compute the argument to "target remote". 204 205proc gdbserver_default_get_remote_address { host port } { 206 # Historically HOST included the trailing ":". 207 # To avoid breaking any board files out there we leave things alone. 208 return "$host$port" 209} 210 211# Default routine to compute the "comm" argument for gdbserver. 212 213proc gdbserver_default_get_comm_port { port } { 214 return ":$port" 215} 216 217# Start a gdbserver process with initial OPTIONS and trailing ARGUMENTS. 218# The port will be filled in between them automatically. 219# 220# Returns the target protocol and socket to connect to. 221 222proc gdbserver_start { options arguments } { 223 global portnum 224 225 # Port id -- either specified in baseboard file, or managed here. 226 if [target_info exists gdb,socketport] { 227 set portnum [target_info gdb,socketport] 228 } else { 229 # Bump the port number to avoid conflicts with hung ports. 230 incr portnum 231 } 232 233 # Extract the local and remote host ids from the target board struct. 234 if [target_info exists sockethost] { 235 set debughost [target_info sockethost] 236 } else { 237 set debughost "localhost:" 238 } 239 240 # Some boards use a different value for the port that is passed to 241 # gdbserver and the port that is passed to the "target remote" command. 242 # One example is the stdio gdbserver support. 243 if [target_info exists gdb,get_remote_address] { 244 set get_remote_address [target_info gdb,get_remote_address] 245 } else { 246 set get_remote_address gdbserver_default_get_remote_address 247 } 248 if [target_info exists gdbserver,get_comm_port] { 249 set get_comm_port [target_info gdbserver,get_comm_port] 250 } else { 251 set get_comm_port gdbserver_default_get_comm_port 252 } 253 254 # Extract the protocol 255 if [target_info exists gdb_protocol] { 256 set protocol [target_info gdb_protocol] 257 } else { 258 set protocol "remote" 259 } 260 261 set gdbserver [find_gdbserver] 262 263 # Loop till we find a free port. 264 while 1 { 265 # Fire off the debug agent. 266 set gdbserver_command "$gdbserver" 267 268 # If gdbserver_reconnect will be called $gdbserver_reconnect_p must be 269 # set to true already during gdbserver_start. 270 global gdbserver_reconnect_p 271 if {![info exists gdbserver_reconnect_p] || !$gdbserver_reconnect_p} { 272 # GDB client could accidentally connect to a stale server. 273 # append gdbserver_command " --debug --once" 274 append gdbserver_command " --once" 275 } 276 277 if { $options != "" } { 278 append gdbserver_command " $options" 279 } 280 if { $portnum != "" } { 281 append gdbserver_command " [$get_comm_port $portnum]" 282 } 283 if { $arguments != "" } { 284 append gdbserver_command " $arguments" 285 } 286 287 global server_spawn_id 288 set server_spawn_id [remote_spawn target $gdbserver_command] 289 290 # GDBserver doesn't do inferior I/O through GDB. But we can 291 # talk to the program using GDBserver's tty instead. 292 global inferior_spawn_id 293 set inferior_spawn_id $server_spawn_id 294 295 # Wait for the server to open its TCP socket, so that GDB can connect. 296 expect { 297 -i $server_spawn_id 298 -timeout 120 299 -notransfer 300 -re "Listening on" { } 301 -re "Can't bind address: Address already in use\\.\r\n" { 302 verbose -log "Port $portnum is already in use." 303 if ![target_info exists gdb,socketport] { 304 # Bump the port number to avoid the conflict. 305 wait -i $expect_out(spawn_id) 306 incr portnum 307 continue 308 } 309 } 310 timeout { 311 error "Timeout waiting for gdbserver response." 312 } 313 } 314 break 315 } 316 317 return [list $protocol [$get_remote_address $debughost $portnum]] 318} 319 320# Start a gdbserver process running SERVER_EXEC, and connect GDB 321# to it. CHILD_ARGS are passed to the inferior. 322# 323# Returns the target protocol and socket to connect to. 324 325proc gdbserver_spawn { child_args } { 326 set target_exec [gdbserver_download_current_prog] 327 328 # Fire off the debug agent. This flavour of gdbserver takes as 329 # arguments the port information, the name of the executable file to 330 # be debugged, and any arguments. 331 set arguments "$target_exec" 332 if { $child_args != "" } { 333 append arguments " $child_args" 334 } 335 return [gdbserver_start "" $arguments] 336} 337 338# Close the GDBserver connection. 339 340proc close_gdbserver {} { 341 global server_spawn_id 342 343 # We can't just call close, because if gdbserver is local then that means 344 # that it will get a SIGHUP. Doing it this way could also allow us to 345 # get at the inferior's input or output if necessary, and means that we 346 # don't need to redirect output. 347 348 if {![info exists server_spawn_id]} { 349 return 350 } 351 352 verbose "Quitting GDBserver" 353 354 catch "close -i $server_spawn_id" 355 catch "wait -i $server_spawn_id" 356 unset server_spawn_id 357} 358 359# Hook into GDB exit, and close GDBserver. We must load this 360# explicitly here, and rename the procedures we want to override. 361load_lib mi-support.exp 362 363if { [info procs gdbserver_orig_gdb_exit] == "" } { 364 rename gdb_exit gdbserver_orig_gdb_exit 365 rename mi_gdb_exit gdbserver_orig_mi_gdb_exit 366} 367 368proc gdbserver_gdb_exit { is_mi } { 369 global gdb_spawn_id server_spawn_id 370 global gdb_prompt 371 global gdbserver_reconnect_p 372 373 # Leave GDBserver running if we're exiting GDB in order to 374 # reconnect to the same instance of GDBserver again. 375 if {[info exists gdbserver_reconnect_p] && $gdbserver_reconnect_p} { 376 if { $is_mi } { 377 gdbserver_orig_mi_gdb_exit 378 } else { 379 gdbserver_orig_gdb_exit 380 } 381 return 382 } 383 384 if {[info exists gdb_spawn_id] && [info exists server_spawn_id]} { 385 # GDB may be terminated in an expected way or an unexpected way, 386 # but DejaGNU doesn't know that, so gdb_spawn_id isn't unset. 387 # Catch the exceptions. 388 catch { 389 if { $is_mi } { 390 set monitor_exit "-interpreter-exec console \"monitor exit\"" 391 } else { 392 set monitor_exit "monitor exit" 393 } 394 send_gdb "$monitor_exit\n"; 395 # We use expect rather than gdb_expect because 396 # we want to suppress printing exception messages, otherwise, 397 # remote_expect, invoked by gdb_expect, prints the exceptions. 398 expect { 399 -i "$gdb_spawn_id" -re "$gdb_prompt $" { 400 exp_continue 401 } 402 -i "$server_spawn_id" eof { 403 wait -i $expect_out(spawn_id) 404 unset server_spawn_id 405 } 406 } 407 } 408 } 409 close_gdbserver 410 411 if { $is_mi } { 412 gdbserver_orig_mi_gdb_exit 413 } else { 414 gdbserver_orig_gdb_exit 415 } 416} 417 418proc gdb_exit {} { 419 gdbserver_gdb_exit 0 420} 421 422proc mi_gdb_exit {} { 423 gdbserver_gdb_exit 1 424} 425 426# Start a gdbserver process running HOST_EXEC and pass CHILD_ARGS 427# to it. Return 0 on success, or non-zero on failure: 2 if gdbserver 428# failed to start or 1 if we couldn't connect to it. 429 430proc gdbserver_run { child_args } { 431 global gdbserver_protocol 432 global gdbserver_gdbport 433 434 # Kill anything running before we try to start gdbserver, in case 435 # we are sharing a serial connection. 436 global gdb_prompt 437 send_gdb "kill\n" 438 gdb_expect 120 { 439 -re "Kill the program being debugged. .y or n. $" { 440 send_gdb "y\n" 441 verbose "\t\tKilling previous program being debugged" 442 exp_continue 443 } 444 -re "$gdb_prompt $" { 445 # OK. 446 } 447 } 448 449 if { [catch { gdbserver_spawn $child_args } res] == 1 } { 450 perror $res 451 return 2 452 } 453 set gdbserver_protocol [lindex $res 0] 454 set gdbserver_gdbport [lindex $res 1] 455 456 return [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] 457} 458 459# Reconnect to the previous gdbserver session. 460 461proc gdbserver_reconnect { } { 462 global gdbserver_protocol 463 global gdbserver_gdbport 464 465 global gdbserver_reconnect_p 466 if {![info exists gdbserver_reconnect_p] || !$gdbserver_reconnect_p} { 467 error "gdbserver_reconnect_p is not set before gdbserver_reconnect" 468 return 0 469 } 470 471 return [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] 472} 473 474# Start gdbserver in extended mode with OPTIONS and connect to it. Note 475# this frobs $gdbserver_protocol, so should be used only from a board 476# that usually connects in target remote mode. 477proc gdbserver_start_extended { {options ""} } { 478 global gdbserver_protocol 479 global gdbserver_gdbport 480 global use_gdb_stub 481 482 set gdbserver_options "--multi" 483 484 if { $options != "" } { 485 append gdbserver_options " $options" 486 } 487 488 if { [catch { gdbserver_start $gdbserver_options "" } res] == 1 } { 489 perror $res 490 return 2 491 } 492 set gdbserver_protocol [lindex $res 0] 493 if { [string first "extended-" $gdbserver_protocol] != 0} { 494 set gdbserver_protocol "extended-$gdbserver_protocol" 495 } 496 set gdbserver_gdbport [lindex $res 1] 497 498 # Even if the board file is testing with target remote, our caller 499 # wants to test against gdbserver in extended-remote mode. Make sure to 500 # disable stub-like techniques. 501 set use_gdb_stub 0 502 503 return [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] 504} 505 506# Start and connect to a gdbserver in extended/multi mode. Unlike 507# gdbserver_start_extended, this does not frob $gdbserver_protocol. 508 509proc gdbserver_start_multi { } { 510 global gdbserver_protocol 511 global gdbserver_gdbport 512 513 if { [catch { gdbserver_start "--multi" "" } res] == 1 } { 514 perror $res 515 return 2 516 } 517 set gdbserver_protocol [lindex $res 0] 518 set gdbserver_gdbport [lindex $res 1] 519 520 return [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] 521} 522 523# Start a gdbserver process in multi/extended mode, and have GDB 524# connect to it (MI version). Return 0 on success, or non-zero on 525# failure. 526 527proc mi_gdbserver_start_multi { } { 528 global gdbserver_protocol 529 global gdbserver_gdbport 530 531 if { [catch { gdbserver_start "--multi" "" } res] == 1 } { 532 perror $res 533 return 2 534 } 535 set gdbserver_protocol [lindex $res 0] 536 set gdbserver_gdbport [lindex $res 1] 537 538 return [mi_gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] 539} 540