# Copyright 2012 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

if [is_remote target] {
    # The test always runs locally.
    return 0
}

set test valgrind-infcall
set srcfile $test.c
set executable $test
set binfile ${objdir}/${subdir}/${executable}
if {[build_executable $test.exp $executable $srcfile {debug}] == -1} {
    return -1
}

set test "spawn valgrind"
set cmd "valgrind --vgdb-error=0 $binfile"
set res [remote_spawn host $cmd];
if { $res < 0 || $res == "" } {
    verbose -log "Spawning $cmd failed."
    unsupported $test
    return -1
}
pass $test
# Declare GDB now as running.
set gdb_spawn_id -1

# GDB started by vgdb stops already after the startup is executed, like with
# non-extended gdbserver.  It is also not correct to run/attach the inferior.
set use_gdb_stub 1

set test "valgrind started"
# The trailing '.' differs for different memcheck versions.
gdb_test_multiple "" $test {
    -re "Memcheck, a memory error detector\\.?\r\n" {
	pass $test
    }
    -re "valgrind: failed to start tool 'memcheck' for platform '.*': No such file or directory" {
	unsupported $test
	return -1
    }
    -re "valgrind: wrong ELF executable class" {
	unsupported $test
	return -1
    }
    -re "command not found" {
	# The spawn succeeded, but then valgrind was not found - e.g. if
	# we spawned SSH to a remote system.
	unsupported $test
	return -1
    }
    -re "valgrind: Bad option '--vgdb-error=0'" {
	# valgrind is not >= 3.7.0.
	unsupported $test
	return -1
    }
}

set test "vgdb prompt"
# The trailing '.' differs for different memcheck versions.
gdb_test_multiple "" $test {
    -re "  (target remote | \[^\r\n\]*/vgdb \[^\r\n\]*)\r\n" {
	set vgdbcmd $expect_out(1,string)
	pass $test
    }
}

# Do not kill valgrind.
unset gdb_spawn_id
set board [host_info name]
unset_board_info fileid

clean_restart $executable

gdb_test "$vgdbcmd" " in _start .*" "target remote for vgdb"

gdb_test "monitor v.set gdb_output" "valgrind output will go to gdb.*"

set continue_count 1
while 1 {
    set test "continue #$continue_count"
    gdb_test_multiple "continue" "" {
	-re "Invalid free\\(\\).*: main .*\r\n$gdb_prompt $" {
	    pass $test
	    break
	}
	-re "\r\n$gdb_prompt $" {
	    pass "$test (false warning)"
	}
    }
    set continue_count [expr $continue_count + 1]
}

set test "p gdb_test_infcall ()"
gdb_test_multiple $test $test {
    -re "unhandled instruction bytes.*\r\n$gdb_prompt $" {
	fail $test
    }
    -re "Continuing \\.\\.\\..*\r\n\\\$1 = 2\r\n$gdb_prompt $" {
	pass $test
    }
}
