1# Copyright 2009-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# 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# 22proc 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 # Make sure we're disconnected, in case we're testing with the 86 # native-extended-gdbserver board, where gdb_start/gdb_load spawn 87 # gdbserver and connect to it. 88 gdb_test "disconnect" ".*" 89 90 set vgdbcmd "target remote | vgdb --pid=$vgdbpid" 91 if { $active_at_startup } { 92 gdb_test "$vgdbcmd" " in \\.?_start .*" "target remote for vgdb" 93 } else { 94 # Let $binfile run a bit before attaching. This is a bit of a hack, 95 # in that it lets test-case valgrind-infcall-2.exp run to the point of 96 # nanosleep, which seems to be required to trigger the error condition. 97 # So, without this, we hit 98 # "UNSUPPORTED: gdb.base/valgrind-infcall-2.exp: do printf". 99 exec sleep 1 100 101 # Connect to vgdb. Don't expect to be anywhere in particular. 102 gdb_test "$vgdbcmd" "" "target remote for vgdb" 103 } 104 105 gdb_test "monitor v.set gdb_output" "valgrind output will go to gdb.*" 106 return 0 107} 108 109# 110# Stop vgdb server. 111# 112proc vgdb_stop { } { 113 global valgrind_spawn_id 114 115 # Only if valgrind got stuck. 116 kill_wait_spawned_process $valgrind_spawn_id 117} 118