# This testcase is part of GDB, the GNU debugger.
#
# Copyright 2013-2021 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/>.

# Check that GDB handles GDBserver disconnecting abruptly, in several
# scenarios.

load_lib gdbserver-support.exp

standard_testfile

if {[skip_gdbserver_tests]} {
    return 0
}

if { [build_executable "failed to prepare" ${testfile}] } {
    return -1
}

# Global control variable used by the proc prepare.  Should be set to
# either 'inferior' or 'server'.
#
# In the proc prepare we start gdbserver and extract a pid, which will
# later be killed by calling the proc kill_server.
#
# When KILL_PID_OF is set to 'inferior' then the pid we kill is that
# of the inferior running under gdbserver, when this process dies
# gdbserver itself will exit.
#
# When KILL_PID_OF is set to 'server' then the pid we kill is that of
# the gdbserver itself, this is a much more aggressive strategy and
# exposes different bugs within GDB.
set kill_pid_of "inferior"

# Spawn GDBserver, run to main, extract GDBserver's PID and save it in
# the SERVER_PID global.

proc prepare {} {
    global binfile gdb_prompt srcfile decimal
    global server_pid
    global GDBFLAGS

    save_vars { GDBFLAGS } {
	# If GDB and GDBserver are both running locally, set the sysroot to avoid
	# reading files via the remote protocol.
	if { ![is_remote host] && ![is_remote target] } {
	    set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\""
	}

	clean_restart $binfile
    }

    # Make sure we're disconnected, in case we're testing with an
    # extended-remote board, therefore already connected.
    gdb_test "disconnect" ".*"

    gdbserver_run ""

    # Continue past server_pid assignment.  We do this for both scenarios,
    # to avoid doing a backtrace from _start, which may not trigger remote
    # communication.
    gdb_breakpoint ${srcfile}:[gdb_get_line_number "i = 0;"]
    gdb_continue_to_breakpoint "after server_pid assignment"

    if { $::kill_pid_of == "inferior" } {
	# Get the pid of GDBServer.
	set test "p server_pid"
	set server_pid 0
	gdb_test_multiple $test $test {
	    -re " = ($decimal)\r\n$gdb_prompt $" {
		set server_pid $expect_out(1,string)
		pass $test
	    }
	}
    } else {
	set server_pid [exp_pid -i $::server_spawn_id]
    }

    if {$server_pid == 0} {
	return 0
    }

    return 1
}

# Kill GDBserver using the PID saved by prepare.

proc kill_server {} {
    global server_pid

    remote_exec target "kill -9 $server_pid"
}

# Test issuing "tstatus" right after the connection is dropped.

proc_with_prefix test_tstatus {} {
    if ![prepare] {
	return
    }

    kill_server

    # Enable trace status packet which is disabled after the
    # connection if the remote target doesn't support tracepoint at
    # all.  Otherwise, no RSP packet is sent out.
    gdb_test_no_output "set remote trace-status-packet on"

    # Force GDB to talk with GDBserver, so that we can get the
    # "connection closed" error.
    gdb_test "tstatus" {Remote connection closed|Remote communication error\.  Target disconnected\.: Connection reset by peer\.}
}

# Test unwinding with no debug/unwind info, right after the connection
# is dropped.

proc_with_prefix test_unwind_nosyms {} {
    if ![prepare] {
	return
    }

    # Remove symbols, so that we try to unwind with one of the
    # heuristic unwinders, and read memory from within its sniffer.
    gdb_unload

    kill_server

    gdb_test "bt" "(Target disconnected|Remote connection closed|Remote communication error).*"
}

# Test unwinding with debug/unwind info, right after the connection is
# dropped.

proc_with_prefix test_unwind_syms {} {
    if ![prepare] {
	return
    }

    kill_server

    gdb_test "bt" "(Target disconnected|Remote connection closed|Remote communication error).*"
}

# Test performing a stepi right after the connection is dropped.

proc_with_prefix test_stepi {} {
    if ![prepare] {
	return
    }

    kill_server

    gdb_test "stepi" "(Target disconnected|Remote connection closed|Remote communication error).*"
}

# Run each test twice, see the description of KILL_PID_OF earlier in
# this file for more details.

foreach_with_prefix kill_pid_of { "inferior" "server" } {
    test_tstatus
    test_unwind_nosyms
    test_unwind_syms
    test_stepi
}
