mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-27 04:52:05 +08:00
eff4f69db4
When testing with "maint set target-non-stop on", gdb.server/bkpt-other-inferior.exp sometimes fails like so: (gdb) inferior 2 [Switching to inferior 2 [process 368191] (<noexec>)] [Switching to thread 2.1 (Thread 368191.368191)] [remote] Sending packet: $m7ffff7fd0100,1#5b [remote] Packet received: 48 [remote] Sending packet: $m7ffff7fd0100,1#5b [remote] Packet received: 48 [remote] Sending packet: $m7ffff7fd0100,9#63 [remote] Packet received: 4889e7e8e80c000049 #0 0x00007ffff7fd0100 in ?? () (gdb) PASS: gdb.server/bkpt-other-inferior.exp: inf 2: switch to inferior break -q main Breakpoint 2 at 0x1138: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.server/server.c, line 21. (gdb) PASS: gdb.server/bkpt-other-inferior.exp: inf 2: set breakpoint delete breakpoints Delete all breakpoints? (y or n) y (gdb) [remote] wait: enter [remote] wait: exit FAIL: gdb.server/bkpt-other-inferior.exp: inf 2: delete all breakpoints in delete_breakpoints (timeout) ERROR: breakpoints not deleted Remote debugging from host ::1, port 55876 monitor exit The problem is here: (gdb) [remote] wait: enter The testcase isn't expecting any output after the prompt. Why is that "[remote] wait" output? What happens is that "delete breakpoints" queries the user, and `query` disables/reenables target async, which results in the remote target's async event handler ending up marked: (top-gdb) bt #0 mark_async_event_handler (async_handler_ptr=0x556bffffffff) at ../../src/gdb/async-event.c:295 #1 0x0000556bf71b711f in infrun_async (enable=1) at ../../src/gdb/infrun.c:119 #2 0x0000556bf7471387 in target_async (enable=1) at ../../src/gdb/target.c:3684 #3 0x0000556bf748a0bd in gdb_readline_wrapper_cleanup::~gdb_readline_wrapper_cleanup (this=0x7ffe3cf30eb0, __in_chrg=<optimized out>) at ../../src/gdb/top.c:1074 #4 0x0000556bf74874e2 in gdb_readline_wrapper (prompt=0x556bfa17da60 "Delete all breakpoints? (y or n) ") at ../../src/gdb/top.c:1096 #5 0x0000556bf75111c5 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) (ctlstr=0x556bf7717f34 "Delete all breakpoints? ", defchar=0 '\000', args=0x7ffe3cf31020) at ../../src/gdb/utils.c:893 #6 0x0000556bf751166f in query (ctlstr=0x556bf7717f34 "Delete all breakpoints? ") at ../../src/gdb/utils.c:985 #7 0x0000556bf6f11404 in delete_command (arg=0x0, from_tty=1) at ../../src/gdb/breakpoint.c:13500 ... ... which then later results in a target_wait call: (top-gdb) bt #0 remote_target::wait_ns (this=0x7ffe3cf30f80, ptid=..., status=0xde530314f0802800, options=...) at ../../src/gdb/remote.c:7937 #1 0x0000556bf7369dcb in remote_target::wait (this=0x556bfa0b2180, ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/remote.c:8173 #2 0x0000556bf745e527 in target_wait (ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/target.c:2000 #3 0x0000556bf71be686 in do_target_wait_1 (inf=0x556bfa1573d0, ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/infrun.c:3463 #4 0x0000556bf71be88b in <lambda(inferior*)>::operator()(inferior *) const (__closure=0x7ffe3cf31320, inf=0x556bfa1573d0) at ../../src/gdb/infrun.c:3526 #5 0x0000556bf71bebcd in do_target_wait (wait_ptid=..., ecs=0x7ffe3cf31540, options=...) at ../../src/gdb/infrun.c:3539 #6 0x0000556bf71bf97b in fetch_inferior_event () at ../../src/gdb/infrun.c:3879 #7 0x0000556bf71a27f8 in inferior_event_handler (event_type=INF_REG_EVENT) at ../../src/gdb/inf-loop.c:42 #8 0x0000556bf71cc8b7 in infrun_async_inferior_event_handler (data=0x0) at ../../src/gdb/infrun.c:9220 #9 0x0000556bf6ecb80f in check_async_event_handlers () at ../../src/gdb/async-event.c:327 #10 0x0000556bf76b011a in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:216 ... ... which returns TARGET_WAITKIND_IGNORE. Fix this by only enabling remote output around setting the breakpoint. gdb/testsuite/ChangeLog: * gdb.server/bkpt-other-inferior.exp: Only enable remote output around setting the breakpoint. Change-Id: I2fd152fd9c46b1c5e7fa678cc4d4054dac0b2bd4
96 lines
2.9 KiB
Plaintext
96 lines
2.9 KiB
Plaintext
# Copyright 2019-2021 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/>.
|
|
|
|
# Test that GDB does not access the remote target's memory when
|
|
# setting a breakpoint on a function that only exists in an inferior
|
|
# that is not bound to the remote target.
|
|
|
|
load_lib gdbserver-support.exp
|
|
|
|
standard_testfile server.c
|
|
|
|
if { [skip_gdbserver_tests] } {
|
|
return 0
|
|
}
|
|
|
|
if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
|
|
{debug pthreads}] } {
|
|
return
|
|
}
|
|
|
|
# Make sure we're disconnected, in case we're testing with an
|
|
# extended-remote board, therefore already connected.
|
|
gdb_test "disconnect" ".*"
|
|
|
|
# Leave inferior 1 with the exec target, not connected. Add another
|
|
# inferior, and connect it to gdbserver.
|
|
|
|
gdb_test "add-inferior" "Added inferior 2" \
|
|
"add inferior 2"
|
|
gdb_test "inferior 2" "Switching to inferior 2.*" \
|
|
"switch to inferior 2"
|
|
gdb_test "file ${binfile}" ".*" "load file in inferior 2"
|
|
|
|
set target_exec [gdbserver_download_current_prog]
|
|
|
|
# Start GDBserver.
|
|
set res [gdbserver_start "" $target_exec]
|
|
|
|
# Connect to GDBserver.
|
|
set gdbserver_protocol [lindex $res 0]
|
|
set gdbserver_gdbport [lindex $res 1]
|
|
gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
|
|
|
|
# Discard any symbol files that we have opened.
|
|
set test "discard symbol table"
|
|
gdb_test_multiple "file" $test {
|
|
-re "A program is being debugged already..*Are you sure you want to change the file.*y or n. $" {
|
|
gdb_test "y" ".*" $test \
|
|
{Discard symbol table from `.*'\? \(y or n\) } "y"
|
|
}
|
|
}
|
|
|
|
# At this point:
|
|
#
|
|
# - inferior 1 has symbols, and is not connected to any target.
|
|
# - inferior 2 has no symbols, and is connected to gdbserver.
|
|
|
|
# Setting a breakpoint at some function by name should set a
|
|
# breakpoint on inferior 1, since it has symbols, and should not
|
|
# result in any access to inferior 2's remote target.
|
|
|
|
foreach inf_sel {1 2} {
|
|
with_test_prefix "inf $inf_sel" {
|
|
gdb_test "inferior $inf_sel" "Switching to inferior $inf_sel.*" \
|
|
"switch to inferior"
|
|
|
|
gdb_test_no_output "set debug remote 1"
|
|
|
|
set test "set breakpoint"
|
|
gdb_test_multiple "break -q main" $test {
|
|
-re "Sending packet.*$gdb_prompt $" {
|
|
fail $test
|
|
}
|
|
-re "^break -q main\r\nBreakpoint .* at .*$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
}
|
|
|
|
gdb_test_no_output "set debug remote 0"
|
|
|
|
delete_breakpoints
|
|
}
|
|
}
|