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
283 lines
9.5 KiB
Plaintext
283 lines
9.5 KiB
Plaintext
# Copyright 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 the =breakpoint-deleted notification for a thread-specific
|
|
# breakpoint is sent as soon as the related thread exits, and not when the
|
|
# inferior next stops.
|
|
#
|
|
# This test is based on gdb.threads/thread-bp-deleted.exp.
|
|
|
|
load_lib mi-support.exp
|
|
set MIFLAGS "-i=mi"
|
|
|
|
# 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"])]
|
|
|
|
standard_testfile
|
|
|
|
if { [build_executable "failed to prepare" $testfile $srcfile \
|
|
{debug pthreads}] } {
|
|
return -1
|
|
}
|
|
|
|
foreach_mi_ui_mode mode {
|
|
mi_gdb_exit
|
|
|
|
if {$mode eq "separate"} {
|
|
set start_ops "separate-mi-tty"
|
|
} else {
|
|
set start_ops ""
|
|
}
|
|
|
|
# Restart, but enable non-stop mode, we need it for background
|
|
# execution.
|
|
save_vars { GDBFLAGS } {
|
|
append GDBFLAGS " -ex \"maint set target-non-stop on\""
|
|
append GDBFLAGS " -ex \"set mi-async on\""
|
|
mi_clean_restart $binfile $start_ops
|
|
}
|
|
|
|
mi_runto_main
|
|
|
|
if {![mi_detect_async]} {
|
|
unsupported "async-mode is required"
|
|
continue
|
|
}
|
|
|
|
mi_delete_breakpoints
|
|
|
|
# Place a breakpoint on 'breakpt' and run to this breakpoint.
|
|
mi_create_breakpoint "breakpt" "place breakpoint on breakpt"
|
|
set breakpt_num [mi_get_valueof "/d" "\$bpnum" "INVALID" \
|
|
"get number for breakpt breakpoint"]
|
|
mi_execute_to "exec-continue" "breakpoint-hit" "breakpt" "" \
|
|
".*" ".*" {"" "disp=\"keep\""} \
|
|
"continue to breakpoint in breakpt"
|
|
|
|
# Now drain all the pending output from the CLI if we are using a separate
|
|
# UI.
|
|
if {$mode eq "separate"} {
|
|
with_spawn_id $gdb_main_spawn_id {
|
|
gdb_test_multiple "" "drain CLI output up to breakpoint" {
|
|
-re "Thread 1 \[^\r\n\]+ hit Breakpoint $decimal,\
|
|
breakpt \\(\\) at\
|
|
\[^\r\n\]+\r\n$decimal\\s+\[^\r\n\]+\r\n" {
|
|
pass $gdb_test_name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# This is just for convenience, this refers to the second thread the
|
|
# inferior spawns.
|
|
set worker_thread 2
|
|
|
|
# Create a thread-specific breakpoint.
|
|
mi_create_breakpoint "-p $worker_thread main" \
|
|
"place thread breakpoint on main" \
|
|
-thread "$worker_thread"
|
|
set bpnum [mi_get_valueof "/d" "\$bpnum" "INVALID" \
|
|
"get number for thread-specific breakpoint"]
|
|
|
|
set loc1 [mi_make_breakpoint -number "$breakpt_num"]
|
|
set loc2 [mi_make_breakpoint -number "$bpnum" -thread "$worker_thread"]
|
|
set table_2_locs [mi_make_breakpoint_table [list $loc1 $loc2]]
|
|
set table_1_locs [mi_make_breakpoint_table [list $loc1]]
|
|
|
|
mi_gdb_test "-break-info" \
|
|
"\\^done,$table_2_locs" \
|
|
"-break-info, expecting two locations"
|
|
|
|
# Resume the inferior, at this point the inferior will spin while
|
|
# we interact with it.
|
|
mi_send_resuming_command "exec-continue" "continue"
|
|
|
|
# Look for the thread-exited notification and the breakpoint-deleted
|
|
# notification. When using a single UI we see both the MI and CLI
|
|
# messages. When using a separate MI UI we only see the MI messages.
|
|
set saw_cli_thread_exited false
|
|
set saw_mi_thread_exited false
|
|
set saw_cli_bp_deleted false
|
|
set saw_mi_bp_deleted false
|
|
|
|
# When running with a remote target, the thread-exited event doesn't
|
|
# appear to be pushed from the target to GDB; instead GDB has to fetch the
|
|
# thread list from the target and spot that a thread exited.
|
|
#
|
|
# In order to achieve this, when running with a remote target we run the
|
|
# '-thread-info 99' command. There isn't a thread 99, but GDB doesn't
|
|
# know that until it fetches the thread list. By fetching the thread list
|
|
# GDB will spot that the thread we are interested in has exited.
|
|
if {$is_remote} {
|
|
set cmd "-thread-info 99"
|
|
set attempt_count 5
|
|
} else {
|
|
set cmd ""
|
|
set attempt_count 0
|
|
}
|
|
|
|
|
|
gdb_test_multiple $cmd "collect thread exited output" \
|
|
-prompt "$::mi_gdb_prompt$" {
|
|
|
|
-re "^~\"\\\[Thread \[^\r\n\]+ exited\\\]\\\\n\"\r\n" {
|
|
set saw_cli_thread_exited true
|
|
exp_continue
|
|
}
|
|
|
|
-re "^~\"Thread-specific breakpoint $bpnum deleted -\
|
|
thread $worker_thread no longer in the thread list\\.\\\\n\"\r\n" {
|
|
set saw_cli_bp_deleted true
|
|
exp_continue
|
|
}
|
|
|
|
-re "^=thread-exited,id=\"$worker_thread\",group-id=\"i1\"\r\n" {
|
|
set saw_mi_thread_exited true
|
|
|
|
# The order of the MI notifications depends on the order in which
|
|
# the observers where registered within GDB. If we have not seen
|
|
# the other MI notification yet then keep looking.
|
|
#
|
|
# Additionally, for remote targets, we're going to wait for the
|
|
# output of the '-thread-info 99' command before we check the
|
|
# results.
|
|
if {!$saw_mi_bp_deleted || $is_remote} {
|
|
exp_continue
|
|
}
|
|
|
|
# We get here with a native target; check we saw all the output
|
|
# that we expected.
|
|
if {$mode eq "separate"} {
|
|
gdb_assert { $saw_mi_thread_exited && $saw_mi_bp_deleted \
|
|
&& !$saw_cli_thread_exited \
|
|
&& !$saw_cli_bp_deleted } \
|
|
$gdb_test_name
|
|
} else {
|
|
gdb_assert { $saw_mi_thread_exited && $saw_mi_bp_deleted \
|
|
&& $saw_cli_thread_exited \
|
|
&& $saw_cli_bp_deleted } \
|
|
$gdb_test_name
|
|
}
|
|
}
|
|
|
|
-re "^=breakpoint-deleted,id=\"3\"\r\n" {
|
|
set saw_mi_bp_deleted true
|
|
|
|
# The order of the MI notifications depends on the order in which
|
|
# the observers where registered within GDB. If we have not seen
|
|
# the other MI notification yet then keep looking.
|
|
#
|
|
# Additionally, for remote targets, we're going to wait for the
|
|
# output of the '-thread-info 99' command before we check the
|
|
# results.
|
|
if {!$saw_mi_thread_exited || $is_remote} {
|
|
exp_continue
|
|
}
|
|
|
|
# We get here with a native target; check we saw all the output
|
|
# that we expected.
|
|
if {$mode eq "separate"} {
|
|
gdb_assert { $saw_mi_thread_exited && $saw_mi_bp_deleted \
|
|
&& !$saw_cli_thread_exited \
|
|
&& !$saw_cli_bp_deleted } \
|
|
$gdb_test_name
|
|
} else {
|
|
gdb_assert { $saw_mi_thread_exited && $saw_mi_bp_deleted \
|
|
&& $saw_cli_thread_exited \
|
|
&& $saw_cli_bp_deleted } \
|
|
$gdb_test_name
|
|
}
|
|
}
|
|
|
|
-re "^-thread-info 99\r\n" {
|
|
if {!$is_remote} {
|
|
fail "$gdb_test_name (unexpected output)"
|
|
}
|
|
# This is the command being echoed back, ignore it.
|
|
exp_continue
|
|
}
|
|
|
|
-re "^\\^done,threads=\\\[\\\]\r\n$::mi_gdb_prompt$" {
|
|
|
|
# This is the result of the '-thread-info 99' trick, which is only
|
|
# used in remote mode. If we see this in native mode then
|
|
# something has gone wrong.
|
|
if {!$is_remote} {
|
|
fail "$gdb_test_name (unexpected output)"
|
|
}
|
|
|
|
# If we've not seen any of the expected output yet then maybe the
|
|
# remote thread just hasn't exited yet. Wait a short while and
|
|
# try again.
|
|
if { !$saw_mi_thread_exited && !$saw_mi_bp_deleted \
|
|
&& !$saw_cli_thread_exited && !$saw_cli_bp_deleted \
|
|
&& $attempt_count > 0 } {
|
|
sleep 1
|
|
incr attempt_count -1
|
|
send_gdb "$cmd\n"
|
|
exp_continue
|
|
}
|
|
|
|
# The output has arrived! Check how we did. There are other bugs
|
|
# that come into play here which change what output we'll see.
|
|
gdb_assert { $saw_mi_thread_exited && $saw_mi_bp_deleted \
|
|
&& $saw_cli_thread_exited \
|
|
&& $saw_cli_bp_deleted } $gdb_test_name
|
|
}
|
|
}
|
|
|
|
# When the MI is running on a separate UI the CLI message will be seen
|
|
# over there, but only if we are not running remote. When we are running
|
|
# remote then the thread-exited event will only be triggered as a result
|
|
# of user triggering a refresh of the thread list (hence the '-thread-info
|
|
# 99' trick above). By typing a command we change the current UI to the
|
|
# terminal we are typing at, as a result these CLI style message will
|
|
# actually appear on the MI when using a remote target.
|
|
if {$mode eq "separate" && !$is_remote} {
|
|
with_spawn_id $gdb_main_spawn_id {
|
|
set saw_thread_exited false
|
|
gdb_test_multiple "" "collect cli 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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
mi_gdb_test "-break-info" \
|
|
"\\^done,$table_1_locs" \
|
|
"-break-info, expecting one location"
|
|
|
|
# Set 'do_spin' to zero, this allows the inferior to progress again; we
|
|
# should then hit the breakpoint in 'breakpt' again.
|
|
mi_gdb_test "set var do_spin = 0" \
|
|
[multi_line \
|
|
".*=memory-changed,thread-group=\"i${decimal}\".addr=\"${hex}\",len=\"${hex}\"" \
|
|
"\\^done"] \
|
|
"set do_spin variable in inferior, inferior should now finish"
|
|
mi_expect_stop "breakpoint-hit" "breakpt" ".*" ".*" "$::decimal" \
|
|
{"" "disp=\"keep\""} "stop in breakpt at the end of the test"
|
|
}
|