# Copyright (C) 2013-2024 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/>.
#
# Verify that a thread-specific breakpoint is deleted when the
# corresponding thread is gone.

standard_testfile

if {[gdb_compile_pthreads \
	 "${srcdir}/${subdir}/${srcfile}" \
	 "${binfile}" executable {debug} ] != "" } {
    return -1
}

# Extract and return the thread ID of the thread stopped at function
# FUNC.

proc get_thread_id {func} {
    global gdb_prompt
    global tdlabel_re

    set thre -1
    set test "get $func thread id"
    gdb_test_multiple "info threads" $test {
	-re "(\[0-9\]+)\[^\n\r\]*${tdlabel_re}\[^\n\r\]*$func.*$gdb_prompt $" {
	    # Get the thread's id.
	    set thre $expect_out(1,string)
	    pass $test
	}
    }

    return $thre
}

proc check_thread_specific_breakpoint {non_stop} {
    global gdb_prompt

    if { ![runto_main] } {
	return -1
    }

    set main_thre [get_thread_id "main"]
    if { $main_thre < 0 } {
	return -1
    }

    gdb_breakpoint "start"
    gdb_continue_to_breakpoint "start"

    set start_thre [get_thread_id "start"]
    if { $start_thre < 0 } {
	return -1
    }

    # Check that multiple uses of 'thread' keyword give an error.
    gdb_test "break main thread $start_thre thread $main_thre" \
	"You can specify only one thread\\."

    # Set a thread-specific breakpoint at "main".  This can't ever
    # be hit, but that's OK.
    gdb_breakpoint "main thread $start_thre"
    gdb_test "info break" ".*breakpoint.*thread $start_thre" "breakpoint set"

    # Set breakpoint at a place only reachable after the "start"
    # thread exits.
    gdb_breakpoint "end"

    # Switch back to the main thread, and resume all threads.  The
    # "start" thread exits, and the main thread reaches "end".
    gdb_test "thread $main_thre" \
	"Switching to thread $main_thre.*" \
	"thread $main_thre selected"

    if { $non_stop } {
	set cmd "continue -a"
    } else {
	set cmd "continue"
    }
    set msg_re \
	[join \
	     [list \
		  "Thread-specific breakpoint 3 deleted" \
		  "-" \
		  "thread 2 no longer in the thread list\\."]]

    gdb_test_multiple "$cmd" "continue to end" {
	-re "$\r\n${gdb_prompt} .*${msg_re}\r\n" {
	    pass $gdb_test_name
	}
	-re "\r\n${msg_re}\r\n.*$gdb_prompt " {
	    pass $gdb_test_name
	}
    }

    set test "thread-specific breakpoint was deleted"
    gdb_test_multiple "info breakpoint" $test {
	-re "thread $start_thre\n$gdb_prompt $" {
	    fail $test
	}
	-re "$gdb_prompt $" {
	    pass $test
	}
    }
}

foreach_with_prefix non_stop {on off} {
    save_vars { GDBFLAGS } {
	append GDBFLAGS " -ex \"set non-stop $non_stop\""
	clean_restart $binfile
    }

    check_thread_specific_breakpoint $non_stop
}
