# Copyright (C) 2013-2023 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 . # # 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 } clean_restart ${binfile} # Extract and return the thread ID of the thread stopped at function # FUNC. proc get_thread_id {func} { global gdb_prompt set thre -1 set test "get $func thread id" gdb_test_multiple "info threads" $test { -re "(\[0-9\]+)\[^\n\r\]*Thread\[^\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 {mode} { with_test_prefix "$mode" { 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 } # 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 reacheable 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 { $mode == "non-stop" } { set cmd "continue -a" } else { set cmd "continue" } set test "continue to end" set thread_exited 0 set prompt 0 gdb_test_multiple "$cmd" $test -lbl { -re "(^|\r\n)\\\[Thread \[^\r\n\]* exited](?=\r\n)" { if { $prompt } { pass $gdb_test_name } else { set thread_exited 1 exp_continue } } -re "\r\n$gdb_prompt " { if { $thread_exited } { pass $gdb_test_name } else { set prompt 1 exp_continue } } } 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 } } } } # Test all-stop mode. check_thread_specific_breakpoint "all-stop" clean_restart ${binfile} # Test non-stop mode. gdb_test_no_output "set non-stop on" "set non-stop mode" check_thread_specific_breakpoint "non-stop"