# Copyright 2015-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 . # Test running a program that spawns enough threads that the tid of an # exited thread is reused. GDB should not crash when this happens. standard_testfile if {[prepare_for_testing "failed to prepare" $testfile $srcfile { debug pthreads }] == -1} { return -1 } if ![runto_main] { return -1 } delete_breakpoints # Avoid dumping a ton of thread create/exit info in the logs. gdb_test_no_output "set print thread-events off" gdb_breakpoint "after_count" gdb_continue_to_breakpoint "after_count" # Get value of VARIABLE in the inferior. proc getvar {variable} { global decimal global gdb_prompt set value 0 set msg "get $variable" gdb_test_multiple "print $variable" $msg { -re " = ($decimal)\r\n$gdb_prompt $" { set value $expect_out(1,string) pass $msg } } return $value } set reuse_time [getvar "reuse_time"] # Now the real test. Run to a breakpoint in a thread that exits # immediately once resumed. The thread ends up left on the thread # list, marked exited (exactly because it's the selected thread). gdb_breakpoint "do_nothing_thread_func" gdb_continue_to_breakpoint "do_nothing_thread_func" delete_breakpoints # Let the program continue, constantly spawning short-lived threads # (one at a time). On some targets, after a bit, a new thread reuses # the tid of the old exited thread that we still have selected. GDB # should not crash in this situation. Of course, if the tid number # space is shared between all processes in the system (such as on # Linux), there's a chance that some other process grabs the TID, but # that can never cause a spurious test fail. gdb_breakpoint "after_reuse_time" # Higher than what the test program sleeps before exiting. set timeout [expr $reuse_time * 2] gdb_continue_to_breakpoint "after_reuse_time"