1 # Copyright 2009-2024 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 # Generic subroutines for handling valgrind vgdb server. 17 18 # 19 # Start a vgdb server, and connect gdb to it. Return 0 on success, and -1 on 20 # error. 21 # 22 proc vgdb_start { {active_at_startup 1} } { 23 global binfile use_gdb_stub board testfile 24 global valgrind_spawn_id gdb_spawn_id 25 global decimal 26 27 set test "spawn valgrind" 28 set cmd_list [list] 29 lappend cmd_list "valgrind" 30 if { $active_at_startup } { 31 lappend cmd_list "--vgdb-error=0" 32 } 33 lappend cmd_list $binfile 34 set cmd [join $cmd_list] 35 set res [remote_spawn host $cmd] 36 if { $res < 0 || $res == "" } { 37 verbose -log "Spawning $cmd failed." 38 unsupported $test 39 return -1 40 } 41 pass $test 42 # Declare GDB now as running. 43 set gdb_spawn_id $res 44 45 # GDB started by vgdb stops already after the startup is executed, like with 46 # non-extended gdbserver. It is also not correct to run/attach the inferior. 47 set use_gdb_stub 1 48 49 set test "valgrind started" 50 # The trailing '.' differs for different memcheck versions. 51 gdb_test_multiple "" $test { 52 -re "==($decimal)== Memcheck, a memory error detector\\.?\r\n" { 53 set vgdbpid $expect_out(1,string) 54 pass $test 55 } 56 -re "valgrind: failed to start tool 'memcheck' for platform '.*': No such file or directory" { 57 unsupported $test 58 return -1 59 } 60 -re "valgrind: wrong ELF executable class" { 61 unsupported $test 62 return -1 63 } 64 -re "command not found" { 65 # The spawn succeeded, but then valgrind was not found - e.g. if 66 # we spawned SSH to a remote system. 67 unsupported $test 68 return -1 69 } 70 -re "valgrind: Bad option.*--vgdb-error=0" { 71 # valgrind is not >= 3.7.0. 72 unsupported $test 73 return -1 74 } 75 } 76 77 # Do not kill valgrind. 78 set valgrind_spawn_id [board_info host fileid] 79 unset gdb_spawn_id 80 set board [host_info name] 81 unset_board_info fileid 82 83 clean_restart $testfile 84 85 set_remotetimeout 4 86 87 # Make sure we're disconnected, in case we're testing with the 88 # native-extended-gdbserver board, where gdb_start/gdb_load spawn 89 # gdbserver and connect to it. 90 gdb_test "disconnect" ".*" 91 92 set vgdbcmd "target remote | vgdb --wait=2 --max-invoke-ms=2500 --pid=$vgdbpid" 93 94 if { $active_at_startup } { 95 set start_re1 " in \\.?_start " 96 set start_re2 "\\.?_start \\(\\) at " 97 set start_re3 "$::hex in \\?\\? \\(\\) from " 98 gdb_test "$vgdbcmd" "($start_re1|$start_re2|$start_re3).*" \ 99 "target remote for vgdb" 100 } else { 101 # Let $binfile run a bit before attaching. This is a bit of a hack, 102 # in that it lets test-case valgrind-infcall-2.exp run to the point of 103 # nanosleep, which seems to be required to trigger the error condition. 104 # So, without this, we hit 105 # "UNSUPPORTED: gdb.base/valgrind-infcall-2.exp: do printf". 106 exec sleep 1 107 108 # Connect to vgdb. Don't expect to be anywhere in particular. 109 gdb_test "$vgdbcmd" "" "target remote for vgdb" 110 } 111 112 gdb_test "monitor v.set gdb_output" "valgrind output will go to gdb.*" 113 return 0 114 } 115 116 # 117 # Stop vgdb server. 118 # 119 proc vgdb_stop { } { 120 global valgrind_spawn_id 121 122 # Only if valgrind got stuck. 123 kill_wait_spawned_process $valgrind_spawn_id 124 } 125