forked from Imagelibrary/binutils-gdb
Usually with test-case gdb.python/py-progspace-events.exp I get:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 4116] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 4116))]^M
28 { /* Nothing. */ }^M
(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1
step^M
FreeProgspaceEvent: <gdb.Progspace object at 0xabf4f850>^M
do_parent_stuff () at py-progspace-events.c:41^M
41 ++global_var;^M
(gdb) PASS: gdb.python/py-progspace-events.exp: step
...
But occasionally I run into the following FAIL:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 5199] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M
28 { /* Nothing. */ }^M
(gdb) FreeProgspaceEvent: <gdb.Progspace object at 0xabaf03a0>^M
FAIL: gdb.python/py-progspace-events.exp: inferior 1 (timeout)
...
This is caused by a race between the handling of an event, and the
"inferior 1" command.
In the passing case, the event is handled first. During which prune_inferiors
is called, but it can't remove inferior 2, because it's still the current one.
In the failing case, the "inferior 1" command is handled first. Then during
handling of the event, prune_inferiors is called, and it can remove inferior 2
because it's no longer the current one.
This looks like a test-case issue to me, but ISTM that we can do better: by
calling prune_inferiors asap, at the end of the "inferior 1" command, we
stabilize the moment when the inferior is removed:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 5199] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M
28 { /* Nothing. */ }^M
FreeProgspaceEvent: <gdb.Progspace object at 0xabaf03a0>^M
(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1
...
This also allows us to simplify the test-case by removing the step command,
which is no longer required to trigger the pruning of the inferior.
Tested on x86_64-linux.
Approved-by: Kevin Buettner <kevinb@redhat.com>
PR gdb/31440
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31440
105 lines
3.1 KiB
Plaintext
105 lines
3.1 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/>.
|
|
|
|
# This file is part of the GDB testsuite. It tests the program space
|
|
# related events in the Python API.
|
|
|
|
load_lib gdb-python.exp
|
|
|
|
require allow_python_tests
|
|
|
|
standard_testfile
|
|
|
|
if {[prepare_for_testing "preparing" $testfile $srcfile] == -1} {
|
|
return -1
|
|
}
|
|
|
|
set pyfile [gdb_remote_download host ${srcdir}/${subdir}/py-progspace-events.py]
|
|
gdb_test_no_output "source ${pyfile}" "load python file"
|
|
|
|
if {![runto_main]} {
|
|
return
|
|
}
|
|
|
|
gdb_breakpoint breakpt
|
|
|
|
gdb_continue_to_breakpoint "run to breakpt function"
|
|
|
|
gdb_test_no_output "set detach-on-fork off"
|
|
|
|
# Continue until the parent process forks and a new child is added.
|
|
# Done this way so we can count the new progspace events; we expect to
|
|
# see exactly one.
|
|
set new_progspace_event_count 0
|
|
gdb_test_multiple "continue" "continue until child process appears" {
|
|
-re "^NewProgspaceEvent: <gdb.Progspace object at $hex>\r\n" {
|
|
# This is a correctly formed event line.
|
|
incr new_progspace_event_count
|
|
exp_continue
|
|
}
|
|
|
|
-re "^NewProgspaceEvent:\[^\r\n\]+\r\n" {
|
|
# This is an incorrectly formed event line.
|
|
fail $gdb_test_name
|
|
}
|
|
|
|
-re "^$gdb_prompt $" {
|
|
pass $gdb_test_name
|
|
}
|
|
|
|
-re "^\[^\r\n\]*\r\n" {
|
|
exp_continue
|
|
}
|
|
}
|
|
|
|
gdb_assert { $new_progspace_event_count == 1 } \
|
|
"only a single new progspace event seen"
|
|
|
|
# Switch to inferior 2 and continue until we hit breakpt.
|
|
gdb_test "inferior 2" "\\\[Switching to inferior 2 .*"
|
|
gdb_continue_to_breakpoint "run to breakpt in inferior 2"
|
|
|
|
# Let inferior 2 exit. The new program space is not removed at this
|
|
# point.
|
|
gdb_test "continue" \
|
|
[multi_line \
|
|
"^Continuing\\." \
|
|
"\\\[Inferior $decimal \[^\r\n\]+ exited normally\\\]"] \
|
|
"continue until inferior 2 exits"
|
|
|
|
# Switch to inferior 1. During this process GDB will prune the now
|
|
# defunct inferior, which deletes its program space, which should
|
|
# trigger the FreeProgspaceEvent.
|
|
#
|
|
|
|
gdb_test "inferior 1" \
|
|
[multi_line \
|
|
"\\\[Switching to inferior 1 .*" \
|
|
".*" \
|
|
"FreeProgspaceEvent.*: <gdb.Progspace object at $hex>"]
|
|
|
|
# Let this inferior run to completion.
|
|
gdb_continue_to_end
|
|
|
|
# Check the program space events trigger when a new inferior is
|
|
# manually added and removed.
|
|
gdb_test "add-inferior" \
|
|
[multi_line \
|
|
"^NewProgspaceEvent: <gdb.Progspace object at $hex>" \
|
|
"\\\[New inferior 3\\\]" \
|
|
"Added inferior 3\[^\r\n\]*"]
|
|
gdb_test "remove-inferior 3" \
|
|
"^FreeProgspaceEvent: <gdb.Progspace object at $hex>"
|