# Copyright 2020-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/>.

# Test loading two inferiors into GDB, and running one of them twice
# in a row.  GDB used to have a bug that made it so that after an
# inferior exit, the current program space was left pointing to the
# wrong inferior's pspace, causing subsequent symbol lookups to
# misbehave, including failing to load libthread_db.so.  See PR
# gdb/25410.

# Build two executables, with different symbols.

set exec1 "multi-re-run-1"
set srcfile1 multi-re-run-1.c
set binfile1 [standard_output_file ${exec1}]

set exec2 "multi-re-run-2"
set srcfile2 multi-re-run-2.c
set binfile2 [standard_output_file ${exec2}]

with_test_prefix "exec1" {
    if { [build_executable "failed to prepare" ${exec1} "${srcfile1}" \
	      [list pthreads debug]] } {
	return -1
    }
}

with_test_prefix "exec2" {
    if { [build_executable "failed to prepare" ${exec2} "${srcfile2}" \
	      [list pthreads debug]] } {
	return -1
    }
}

# Start two inferiors, leave one stopped, and run the other a couple
# times.  RE_RUN_INF is the inferior that is re-run.

proc test_re_run {re_run_inf} {
    global binfile1 binfile2
    global inferior_exited_re
    global gdb_prompt
    global last_loaded_file

    clean_restart ${binfile1}

    delete_breakpoints

    # Start another inferior.
    gdb_test "add-inferior" "Added inferior 2.*" \
	"add empty inferior 2"
    gdb_test "inferior 2" "Switching to inferior 2.*" \
	"switch to inferior 2"
    gdb_load ${binfile2}

    if {$re_run_inf == 1} {
	set steady_inf 2
	set steady_binfile $binfile2
	set re_run_binfile $binfile1
    } else {
	set steady_inf 1
	set steady_binfile $binfile1
	set re_run_binfile $binfile2
    }

    gdb_test "inferior $steady_inf" "Switching to inferior $steady_inf.*" \
	"switch to steady inferior"
    set last_loaded_file $steady_binfile

    # Run the steady inferior to a breakpoint, and let it stay stopped
    # there.
    if ![runto all_started] then {
	return 0
    }

    gdb_test "inferior $re_run_inf" "Switching to inferior $re_run_inf.*" \
	"switch to re-run inferior"
    set last_loaded_file $re_run_binfile

    # Now run the RE_RUN_INF inferior a couple times.  GDB used to
    # have a bug that caused the second run to fail to load
    # libthread_db.so.
    foreach_with_prefix iter {1 2} {
	delete_breakpoints

	if ![runto all_started] {
	    return 0
	}

	# If a thread_stratum target fails to load, then TLS debugging
	# fails too.
	gdb_test "print tls_var" " = 1"

	gdb_continue_to_end "" continue 1

	# In the original bug, after an inferior exit, GDB would leave
	# the current program space pointing to the wrong inferior's
	# pspace, and thus the wrong symbols were visible.
	if {$re_run_inf == 1} {
	    gdb_test "print re_run_var_1" " = 1"
	} else {
	    gdb_test "print re_run_var_2" " = 2"
	}
    }
}

# For completeness, test re-running either inferior 1 or inferior 2.
foreach_with_prefix re_run_inf {1 2} {
    test_re_run $re_run_inf
}
