# Copyright (C) 2015-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/>.

# This test verifies that several threads forking while another thread
# is constantly stepping over a breakpoint is properly handled.

standard_testfile

set linenum [gdb_get_line_number "set break here"]

if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}] == -1} {
    return -1
}

# Assume yes.
set displaced_stepping_supported 1

# "set displaced on" only tells gdb to use displaced stepping if
# possible.  Probe for actual support.

proc probe_displaced_stepping_support {} {
    global displaced_stepping_supported
    global binfile gdb_prompt

    with_test_prefix "probe displaced-stepping support" {
	clean_restart $binfile

	gdb_test_no_output "set displaced on"
	if ![runto_main] then {
	    return 0
	}

	# We're stopped at the main breakpoint.  If displaced stepping is
	# supported, we'll see related debug output while we step past
	# that breakpoint.
	gdb_test_no_output "set debug displaced 1"
	gdb_test_multiple "next" "probe" {
	    -re "prepared successfully .*$gdb_prompt $" {
		pass "supported"
	    }
	    -re ".*$gdb_prompt $" {
		set displaced_stepping_supported 0
		pass "not supported"
	    }
	}
    }
}

# The test proper.  If COND_BP_TARGET is true, then test with
# conditional breakpoints evaluated on the target side, if possible.
# DETACH_ON_FORK is used as value for the "set detach-on-fork"
# setting.  If "on", this exercises GDB explicitly continuing the fork
# child until exit.  If "off", this exercises GDB detaching the fork
# child.  DISPLACED indicates whether to use displaced stepping or
# not.
proc do_test { cond_bp_target detach_on_fork displaced } {
    global GDBFLAGS
    global srcfile testfile binfile
    global decimal gdb_prompt
    global linenum
    global is_remote_target

    set saved_gdbflags $GDBFLAGS
    set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop on\""]
    clean_restart $binfile
    set GDBFLAGS $saved_gdbflags

    if ![runto_main] then {
	return 0
    }

    if {$cond_bp_target} {
	set test "set breakpoint condition-evaluation target"
	gdb_test_multiple $test $test {
	    -re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
		# Target doesn't support breakpoint condition
		# evaluation on its side.  Skip the test.
		return 0
	    }
	    -re "^$test\r\n$gdb_prompt $" {
	    }
	}
    } else {
	gdb_test_no_output "set breakpoint condition-evaluation host"
    }

    gdb_test_no_output "set detach-on-fork $detach_on_fork"
    gdb_test_no_output "set displaced $displaced"

    gdb_test "break $linenum if zero == 1" \
	"Breakpoint .*" \
	"set breakpoint that evals false"

    set test "continue &"
    gdb_test_multiple $test $test {
	-re "$gdb_prompt " {
	    pass $test
	}
    }

    set fork_count 0
    set ok 0

    with_timeout_factor 10 {
        set test "inferior 1 exited"
        gdb_test_multiple "" $test {
	    -re "Inferior 1 \(\[^\r\n\]+\) exited normally" {
	        set ok 1
	        pass $test
	    }
	    -re "Inferior $decimal \(\[^\r\n\]+\) exited normally" {
	        incr fork_count
	        if {$fork_count <= 100} {
		    exp_continue
	        } else {
		    fail "$test (too many forks)"
	        }
	    }
	}
    }

    if {!$ok} {
	# No use testing further.
	return
    }

    gdb_test "info threads" "No threads\." \
	"no threads left"

    gdb_test "info inferiors" \
	"Num\[ \t\]+Description\[ \t\]+Connection\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \
	"only inferior 1 left"
}

probe_displaced_stepping_support

foreach_with_prefix cond_bp_target {1 0} {
    foreach_with_prefix detach_on_fork {"on" "off"} {
	# Disable "off" for now.  The test does pass with
	# detach-on-fork off (at the time of writing), but gdb seems
	# to slow down quadratically as inferiors are created, and
	# then the test takes annoyingly long to complete...
	if {$detach_on_fork == "off"} {
	    continue
	}

	foreach_with_prefix displaced {"on" "off"} {
	    if {$displaced == "on" && !$displaced_stepping_supported} {
		continue
	    }

	    do_test $cond_bp_target $detach_on_fork $displaced
	}
    }
}
