CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
201 lines
7.2 KiB
Plaintext
201 lines
7.2 KiB
Plaintext
# Copyright (C) 2023-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/>.
|
|
|
|
# Check that 'maint info breakpoints' succeeds in the period of time
|
|
# between a thread-specific breakpoint being deleted, and GDB next
|
|
# stopping.
|
|
#
|
|
# There used to be a bug where GDB would try to lookup the thread for
|
|
# the thread-specific breakpoint, the thread of course having been
|
|
# deleted, couldn't be found, and GDB would end up dereferencing a
|
|
# nullptr.
|
|
|
|
standard_testfile
|
|
|
|
if {[build_executable "failed to prepare" $testfile $srcfile \
|
|
{debug pthreads}] == -1} {
|
|
return -1
|
|
}
|
|
|
|
# We need to do things a little differently when using the remote protocol.
|
|
set is_remote \
|
|
[expr [target_info exists gdb_protocol] \
|
|
&& ([string equal [target_info gdb_protocol] "remote"] \
|
|
|| [string equal [target_info gdb_protocol] "extended-remote"])]
|
|
|
|
# This test requires background execution, which relies on non-stop mode.
|
|
save_vars { GDBFLAGS } {
|
|
append GDBFLAGS " -ex \"maint set target-non-stop on\""
|
|
clean_restart ${binfile}
|
|
}
|
|
|
|
if {![runto_main]} {
|
|
return -1
|
|
}
|
|
|
|
# Check we hace non-stop mode. We do try to force this on above, but maybe
|
|
# the target doesn't support non-stop mode, in which case (hopefully)
|
|
# non-stop mode will still show as off, and this test should not be run.
|
|
if {![is_target_non_stop]} {
|
|
unsupported "required non-stop mode"
|
|
return -1
|
|
}
|
|
|
|
delete_breakpoints
|
|
|
|
gdb_breakpoint "breakpt"
|
|
gdb_continue_to_breakpoint "continue to first breakpt call"
|
|
set breakpt_num [get_integer_valueof "\$bpnum" "INVALID" \
|
|
"get number for breakpoint in breakpt"]
|
|
|
|
# Check info threads just to confirm the thread numbering. The rest
|
|
# of this script just assumes we have threads numbered 1 and 2.
|
|
gdb_test "info threads" \
|
|
[multi_line \
|
|
"\\* 1\\s+Thread \[^\r\n\]+" \
|
|
" 2\\s+Thread \[^\r\n\]+"]
|
|
|
|
set main_thread 1
|
|
set worker_thread 2
|
|
|
|
# Check the 'info breakpoints' output for the thread-specific breakpoint
|
|
# numbered BPNUM. If EXPECTED is true then the breakpoint is expected to be
|
|
# present, otherwise, the breakpoint is expected not to be present.
|
|
|
|
proc check_for_thread_specific_breakpoint { testname bpnum expected } {
|
|
set saw_thread_specific_bp false
|
|
gdb_test_multiple "info breakpoints" $testname {
|
|
-re "^(\[^\r\n\]+)\r\n" {
|
|
set line $expect_out(1,string)
|
|
if { [regexp "$bpnum\\s+breakpoint\[^\r\n\]+ $::hex in main\
|
|
at \[^\r\n\]+" $line] } {
|
|
set saw_thread_specific_bp true
|
|
}
|
|
exp_continue
|
|
}
|
|
-re "^$::gdb_prompt $" {
|
|
set result [expr $expected ? $saw_thread_specific_bp \
|
|
: !$saw_thread_specific_bp]
|
|
gdb_assert { $result } $gdb_test_name
|
|
}
|
|
}
|
|
}
|
|
|
|
# Create a thread-specific breakpoint. This will never actually be hit; we
|
|
# don't care, we just want to see GDB auto-delete this breakpoint.
|
|
gdb_breakpoint "main thread $worker_thread" \
|
|
"create a thread-specific breakpoint"
|
|
set bpnum [get_integer_valueof "\$bpnum" "INVALID" \
|
|
"get number for thread-specific breakpoint"]
|
|
|
|
# Check the thread-specific breakpoint is present in 'info breakpoints'.
|
|
check_for_thread_specific_breakpoint \
|
|
"check for thread-specific b/p before thread exit" $bpnum true
|
|
|
|
# Continue in async mode. After this the worker thread will exit.
|
|
# The -no-prompt-anchor is needed here as sometimes the exit of the
|
|
# worker thread will happen so quickly that expect will see the
|
|
# 'thread exited' message immediately after the prompt, which breaks
|
|
# the normal gdb_test prompt anchoring.
|
|
gdb_test -no-prompt-anchor "continue&" "Continuing\\."
|
|
|
|
if {$is_remote} {
|
|
# Collect the output from GDB telling us that the thread exited.
|
|
# Unfortunately in the remote protocol the thread-exited event doesn't
|
|
# appear to be pushed to GDB, instead we rely on GDB asking about the
|
|
# threads (which isn't great).
|
|
#
|
|
# So, what we do here is ask about thread 99, which hopefully shouldn't
|
|
# exist, however, in order to answer that question GDB has to grab the
|
|
# thread list from the remote, at which point GDB will spot that one of
|
|
# the threads has exited, and will tell us about it.
|
|
#
|
|
# However, we might be too quick sending the 'info threads 99' command,
|
|
# so, if we see the output of that command without any thread exited
|
|
# text, we wait for a short while and try again. We wait for up to 5
|
|
# seconds (5 tries). However, this might mean on a _really_ slow
|
|
# machine that the thread still hasn't exited. I guess if we start
|
|
# seeing that then we can just update ATTEMPT_COUNT below.
|
|
set saw_thread_exited false
|
|
set saw_bp_deleted false
|
|
set attempt_count 5
|
|
gdb_test_multiple "info threads 99" "collect thread exited output" {
|
|
-re "info threads 99\r\n" {
|
|
exp_continue
|
|
}
|
|
|
|
-re "^\\\[Thread \[^\r\n\]+ exited\\\]\r\n" {
|
|
set saw_thread_exited true
|
|
exp_continue
|
|
}
|
|
|
|
-re "^Thread-specific breakpoint $bpnum deleted -\
|
|
thread $worker_thread no longer in the thread list\\.\r\n" {
|
|
set saw_bp_deleted true
|
|
exp_continue
|
|
}
|
|
|
|
-re "No threads match '99'\\.\r\n$gdb_prompt $" {
|
|
if {!$saw_thread_exited && !$saw_bp_deleted && $attempt_count > 0} {
|
|
sleep 1
|
|
incr attempt_count -1
|
|
send_gdb "info threads 99\n"
|
|
exp_continue
|
|
}
|
|
|
|
gdb_assert { $saw_thread_exited && $saw_bp_deleted } $gdb_test_name
|
|
}
|
|
}
|
|
} else {
|
|
# Collect the output from GDB telling us that the thread exited.
|
|
set saw_thread_exited false
|
|
gdb_test_multiple "" "collect thread exited output" {
|
|
-re "\\\[Thread \[^\r\n\]+ exited\\\]\r\n" {
|
|
set saw_thread_exited true
|
|
exp_continue
|
|
}
|
|
|
|
-re "^Thread-specific breakpoint $bpnum deleted -\
|
|
thread $worker_thread no longer in the thread list\\.\r\n" {
|
|
gdb_assert { $saw_thread_exited } \
|
|
$gdb_test_name
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check the thread-specific breakpoint is no longer present in 'info
|
|
# breakpoints' output.
|
|
check_for_thread_specific_breakpoint \
|
|
"check for thread-specific b/p before after exit" $bpnum false
|
|
|
|
# Check the thread-specific breakpoint doesn't show up in the 'maint
|
|
# info breakpoints' output. And also that this doesn't cause GDB to
|
|
# crash, which it did at one point.
|
|
gdb_test_lines "maint info breakpoints" "" ".*" \
|
|
-re-not "breakpoint\\s+keep\\s+y\\s+$hex\\s+in main at "
|
|
|
|
# Set the do_spin variable in the inferior. This will cause it to drop out
|
|
# of its spin loop and hit the next breakpoint. Remember, at this point the
|
|
# inferior is still executing.
|
|
gdb_test "print do_spin = 0" "\\\$$decimal = 0"
|
|
|
|
# Collect the notification that the inferior has stopped.
|
|
gdb_test_multiple "" "wait for stop" {
|
|
-re "Thread $main_thread \[^\r\n\]+ hit Breakpoint ${breakpt_num},\
|
|
breakpt \\(\\) \[^\r\n\]+\r\n$decimal\\s+\[^\r\n\]+\r\n" {
|
|
pass $gdb_test_name
|
|
}
|
|
}
|