# Copyright (C) 2015-2017 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 {
	    fail "can't run to main"
	    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 "displaced pc to.*$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 {
	fail "can't run to main"
	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\]+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
	}
    }
}
