[PATCH v4 30/44] gdb: keep target registered in inferior_event_handler()
Markus Metzger <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
Even if no threads are currently running, maybe because there are
currently no threads, the target may still generate events, e.g. new
threads getting dispatched onto a GPU, new modules getting loaded, or new
stop replies in response to interrupt requests.
The test (added in a subsequent patch)
gdb.arch/intelgt-interrupt-exited-thread.exp
resumes a GPU inferior with no threads and schedule-multiple off, then
interrupts it. We disable schedule-multiple to mimic a scenario where
we're only debugging the GPU part.
In response to vCtrlC, gdbserver-intelgt sends
%Stop:N
to indicate that there are still no threads on the GPU. GDB, however, is
not able to receive the stop notification, causing the C-c to not have any
effect. Subsequent C-c enqueue more stop replies but are not able to
interrupt the inferior. GDB appears to hang.
Similarly, GDB would not be able to receive %Library notifications,
causing the host inferior to hang when GDB is not acknowledging the new
library.
While we could re-enable target_async() in pass_ctrlc(), this wouldn't
solve the inferior hang on library acknowledgement.
Several tests that enable debug output need changes because there is debug
output after the prompt. Changes are included in this patch.
This patch causes regressions in
gdb.base/multi-forks.exp
because inferiors are pruned from fetch_inferior_event() right after
detaching or killing them, whereas the test expects
<null>
inferiors to remain in the inferior list. Changes to make the test
tolerate the new behavior are included in this patch.
And in
gdb.threads/killed-outside.exp
because the SIGKILL is fetched early, and when the target is resumed, the
command is aborted when regcache_read_pc() throws in status_callback()
from linux_nat_wait_1() because the signalled leader, the only remaining
thread, is still stopped at a breakpoint. This patch contains a fix.
And in
gdb.base/annota-input-while-running.exp
gdb.base/annota1.exp
gdb.cp/annota2.exp
because there may be additional
frames-invalid
annotations after the
pre-prompt
(gdb)
prompt
annotation sequence. Changes to make the tests tolerate the new behavior
are included in this patch.
And in
gdb.threads/process-dies-while-detaching.exp
because exited threads are pruned right after killing them, leaving GDB
without a live thread for the 'continue' command that is expected to
notice thread exits. Changes to make the test tolerate the new behavior
are included in this patch.
And in
gdb.threads/signal-while-stepping-over-bp-other-thread.exp
because of an additional fetch_inferior_event cycle after the prompt.
Changes to make the test tolerate the new behavior are included in this
patch.
---
gdb/inf-loop.c | 11 +++--------
gdb/linux-nat.c | 3 +++
.../gdb.base/annota-input-while-running.exp | 2 +-
gdb/testsuite/gdb.base/annota1.exp | 4 ++--
.../gdb.base/breakpoint-in-ro-region.exp | 4 ++--
gdb/testsuite/gdb.base/multi-forks.exp | 12 +++++++++++-
.../gdb.base/premature-dummy-frame-removal.exp | 16 +++++++++++-----
gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp | 4 ++--
gdb/testsuite/gdb.base/ui-redirect.exp | 2 +-
gdb/testsuite/gdb.cp/annota2.exp | 2 +-
gdb/testsuite/gdb.threads/ia64-sigill.exp | 8 ++++----
.../gdb.threads/process-dies-while-detaching.exp | 5 +++--
...ignal-while-stepping-over-bp-other-thread.exp | 2 +-
.../gdb.threads/stepi-random-signal.exp | 4 ++--
.../gdb.threads/watchthreads-reorder.exp | 4 ++--
15 files changed, 49 insertions(+), 34 deletions(-)
diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c
index 95fd4f8a2c5..a68eb740d93 100644
--- a/gdb/inf-loop.c
+++ b/gdb/inf-loop.c
@@ -43,14 +43,9 @@ inferior_event_handler (enum inferior_event_type event_type)
break;
case INF_EXEC_COMPLETE:
- if (!non_stop)
- {
- /* Unregister the inferior from the event loop. This is done
- so that when the inferior is not running we don't get
- distracted by spurious inferior output. */
- if (target_has_execution () && target_can_async_p ())
- target_async (false);
- }
+ /* We need to keep the inferior registered with the event loop.
+ Even if there are currently no threads in the inferior, so
+ nothing is running, we may get notifications from the target. */
/* Do all continuations associated with the whole inferior (not
a particular thread). */
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 9e015b57379..f28e9367c2c 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2627,6 +2627,9 @@ status_callback (struct lwp_info *lp)
if (!lwp_status_pending_p (lp))
return false;
+ if (is_lwp_marked_dead (lp))
+ return true;
+
if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
|| lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
{
diff --git a/gdb/testsuite/gdb.base/annota-input-while-running.exp b/gdb/testsuite/gdb.base/annota-input-while-running.exp
index 747175f0ab5..f825bf7a7a3 100644
--- a/gdb/testsuite/gdb.base/annota-input-while-running.exp
+++ b/gdb/testsuite/gdb.base/annota-input-while-running.exp
@@ -36,7 +36,7 @@ if {![runto_main]} {
# gdb_test_multiple.
set old_gdb_prompt $gdb_prompt
-set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
+set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n(\r\n\032\032frames-invalid\r\n)?"
# Like gdb_test, but cope with the annotation prompt.
proc gdb_annota_test {command pattern message} {
diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp
index 35eaf26103e..2839c2de12f 100644
--- a/gdb/testsuite/gdb.base/annota1.exp
+++ b/gdb/testsuite/gdb.base/annota1.exp
@@ -57,7 +57,7 @@ gdb_test "break ${srcfile}:${main_line}" \
# true with this annotated prompt.
set old_gdb_prompt $gdb_prompt
-set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
+set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n(\r\n\032\032frames-invalid\r\n)?"
#
# Escape all the characters in the path that need it. For instance
@@ -546,7 +546,7 @@ proc thread_test {} {
gdb_breakpoint "$linenum"
set gdb_prompt \
- "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
+ "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n(\r\n\032\032frames-invalid\r\n)?"
gdb_test_multiple "set annotate 2" "" {
-re "set annotate 2\r\n$gdb_prompt$" {
diff --git a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
index b7ae91155d4..24bc69a3f90 100644
--- a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
+++ b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
@@ -44,11 +44,11 @@ proc probe_target_hardware_step {} {
gdb_test_no_output "set debug target 1"
set test "probe target hardware step"
gdb_test_multiple "pipe si | grep resume" $test {
- -re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
+ -re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt" {
set hw_step 1
pass $test
}
- -re "$gdb_prompt $" {
+ -re "$gdb_prompt" {
pass $test
}
}
diff --git a/gdb/testsuite/gdb.base/multi-forks.exp b/gdb/testsuite/gdb.base/multi-forks.exp
index 63e83ca023a..a9d6e3ccc98 100644
--- a/gdb/testsuite/gdb.base/multi-forks.exp
+++ b/gdb/testsuite/gdb.base/multi-forks.exp
@@ -186,5 +186,15 @@ gdb_test "detach inferior 5" "Detaching .*" "detach 5"
for {set i 6} { $i <= 16} {incr i} {
gdb_test_no_output "kill inferior $i" "kill $i"
- gdb_test "info inferior $i" "<null>.*" "did kill $i"
+ gdb_test_multiple "info inferior $i" "did kill $i" {
+ -re -wrap "<null>.*" {
+ pass $gdb_test_name
+ }
+ -re -wrap "No inferiors." {
+ pass $gdb_test_name
+ }
+ -re -wrap ".*" {
+ fail $gdb_test_name
+ }
+ }
}
diff --git a/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp b/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp
index 39c59736420..1aaab6369b0 100644
--- a/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp
+++ b/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp
@@ -80,10 +80,16 @@ gdb_test_multiple "p some_func ()" "" {
# debug, to format of which isn't fixed. All we care about is that
# GDB is still running afterwards.
#
-gdb_test_no_output "set debug frame on"
-gdb_test_lines "p some_func ()" \
- "repeat p some_func () with frame debug on" \
- ".*"
-gdb_test_no_output "set debug frame off"
+gdb_test "set debug frame on"
+gdb_test_multiple "p some_func ()" \
+ "repeat p some_func () with frame debug on" {
+ -re "$gdb_prompt" {
+ pass $gdb_test_name
+ }
+ -re "\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+ }
+gdb_test "set debug frame off"
gdb_test "p 1 + 2 + 3" " = 6"
diff --git a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
index be215045048..b7f279b528a 100644
--- a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
+++ b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
@@ -65,11 +65,11 @@ gdb_test_no_output "set debug target 1"
set hardware_step 0
set test "probe target hardware step"
gdb_test_multiple "pipe si | grep resume" $test {
- -re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
+ -re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt" {
set hardware_step 1
pass $test
}
- -re "$gdb_prompt $" {
+ -re "$gdb_prompt" {
pass $test
}
}
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index bed11bd2e87..36c60e38782 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -119,7 +119,7 @@ with_test_prefix "debugging" {
"Copying output to /dev/null.*Copying debug output to /dev/null\\."
gdb_test \
- -prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n$" \
+ -prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n" \
"continue" \
"Continuing.*\\\[infrun\\\] .*\\\[infrun\\\] .*Breakpoint ${::decimal}, foo.*"
diff --git a/gdb/testsuite/gdb.cp/annota2.exp b/gdb/testsuite/gdb.cp/annota2.exp
index 466cab05b8a..7243e74435d 100644
--- a/gdb/testsuite/gdb.cp/annota2.exp
+++ b/gdb/testsuite/gdb.cp/annota2.exp
@@ -62,7 +62,7 @@ gdb_test "break 25" \
#
set old_gdb_prompt $gdb_prompt
-set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
+set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n(\r\n\032\032frames-invalid\r\n)?"
send_gdb "set annotate 2\n"
gdb_expect {
diff --git a/gdb/testsuite/gdb.threads/ia64-sigill.exp b/gdb/testsuite/gdb.threads/ia64-sigill.exp
index b19c62e8ded..782d0dbb3e7 100644
--- a/gdb/testsuite/gdb.threads/ia64-sigill.exp
+++ b/gdb/testsuite/gdb.threads/ia64-sigill.exp
@@ -64,7 +64,7 @@ gdb_test_multiple "continue" "continue" -prompt $prompt {
set ok 1
exp_continue
}
- -re -wrap "" {
+ -re "$gdb_prompt" {
gdb_assert { $ok } $gdb_test_name
}
-re "\r\n\[^\r\n\]*(?=\r\n\[^\r\n\]*\r\n)" {
@@ -72,7 +72,7 @@ gdb_test_multiple "continue" "continue" -prompt $prompt {
}
}
-gdb_test_no_output {delete $sigill_bpnum}
+gdb_test {delete $sigill_bpnum}
set ok 0
gdb_test_multiple "continue" "continue for the pending signal" -prompt $prompt {
@@ -80,10 +80,10 @@ gdb_test_multiple "continue" "continue for the pending signal" -prompt $prompt {
# Breakpoint has been skipped in the other thread.
set ok 1
}
- -re " received signal .*\r\n$gdb_prompt $" {
+ -re " received signal .*\r\n$gdb_prompt" {
fail $gdb_test_name
}
- -re -wrap "" {
+ -re "$gdb_prompt" {
gdb_assert { $ok } $gdb_test_name
}
-re "\r\n\[^\r\n\]*(?=\r\n\[^\r\n\]*\r\n)" {
diff --git a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
index edc15f25b06..fe5e1d42c46 100644
--- a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
+++ b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
@@ -166,6 +166,7 @@ proc do_detach {multi_process cmd child_exit} {
error "unhandled \$child_exit: $child_exit"
}
+ set no_live_thread_re "Cannot execute this command without a live selected thread."
set is_remote [expr {[target_info exists gdb_protocol]
&& [target_info gdb_protocol] == "remote"}]
@@ -184,7 +185,7 @@ proc do_detach {multi_process cmd child_exit} {
} elseif {$cmd == "continue"} {
# Make sure that continuing works and that the parent process
# exits cleanly.
- gdb_test "continue" $continue_re
+ gdb_test "continue" ($continue_re|$no_live_thread_re)
} else {
perror "unhandled command: $cmd"
}
@@ -197,7 +198,7 @@ proc do_detach {multi_process cmd child_exit} {
if {$cmd == "detach"} {
gdb_test "detach" "Detaching from .*, process ${decimal}\r\n\\\[Inferior $decimal \\(.*\\) detached\\\]$extra"
} elseif {$cmd == "continue"} {
- gdb_test "continue" $continue_re
+ gdb_test "continue" ($continue_re|$no_live_thread_re)
} else {
perror "unhandled command: $cmd"
}
diff --git a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
index f7bc6cb36b9..d268299ff4a 100644
--- a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
+++ b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
@@ -97,7 +97,7 @@ gdb_test "set scheduler-locking off"
gdb_test "set debug infrun 1"
set test "step"
-gdb_test_sequence $test $test -prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n$" {
+gdb_test_sequence $test $test -prompt "$gdb_prompt .*\\\[infrun\\\] fetch_inferior_event: exit\r\n$" {
"need to step-over"
"resume_1: step=1,"
"signal arrived while stepping over breakpoint"
diff --git a/gdb/testsuite/gdb.threads/stepi-random-signal.exp b/gdb/testsuite/gdb.threads/stepi-random-signal.exp
index 64b07ec00bb..dc9aca7d759 100644
--- a/gdb/testsuite/gdb.threads/stepi-random-signal.exp
+++ b/gdb/testsuite/gdb.threads/stepi-random-signal.exp
@@ -83,13 +83,13 @@ if {$prev_addr == ""} {
set seen 0
set test "stepi"
-set prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n$"
+set prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n"
if {[gdb_test_multiple "stepi" "$test" -prompt $prompt {
-re {\[infrun\] handle_signal_stop: random signal} {
set seen 1
exp_continue
}
- -re "$prompt$" {
+ -re "$prompt" {
}
}] != 0} {
return
diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.exp b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp
index 192996b51ca..42e611b33ca 100644
--- a/gdb/testsuite/gdb.threads/watchthreads-reorder.exp
+++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp
@@ -89,9 +89,9 @@ foreach reorder {0 1} { with_test_prefix "reorder$reorder" {
# found in the DEBUG_INFRUN code path.
gdb_test "set debug infrun 1"
- set prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n$"
+ set prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n"
gdb_test_multiple "continue" "continue to breakpoint: break-at-exit" -prompt $prompt {
- -re ".*break-at-exit.*$prompt$" {
+ -re ".*break-at-exit.*$prompt" {
pass $gdb_test_name
}
}
--
2.43.0
________________________________________
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 (89) 99143-0
www.intel.de
Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman
Chairperson of the Supervisory Board: Sonja Pierer
Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.