diff options
author | Simon Marchi <simon.marchi@efficios.com> | 2025-07-08 16:54:44 -0400 |
---|---|---|
committer | Simon Marchi <simon.marchi@efficios.com> | 2025-09-02 13:50:21 -0400 |
commit | 3a0bf6d1926c61781d40ec7d948fd9a445f316a8 (patch) | |
tree | 28ef7ff1ab9b4b2670bd3748d5202b4ef26c05a5 /gdb/common/preprocessor.h | |
parent | 0a2ec1daf9339d105e83d73ecabe65e73bb6f84a (diff) | |
download | binutils-3a0bf6d1926c61781d40ec7d948fd9a445f316a8.zip binutils-3a0bf6d1926c61781d40ec7d948fd9a445f316a8.tar.gz binutils-3a0bf6d1926c61781d40ec7d948fd9a445f316a8.tar.bz2 |
gdb/remote: use scoped_restore_current_program_space in remote_unpush_target
Since commit 3cb6bc13e328 ("gdb/progspace: add solib_ops pointer in
program_space"), this fails with an internal error:
$ make check TESTS="gdb.server/extended-remote-restart.exp" RUNTESTFLAGS="--target_board=native-extended-gdbserver"
In gdb.log:
(gdb) PASS: gdb.server/extended-remote-restart.exp: kill: 1, follow-child 0: disconnect
target extended-remote localhost:2347
Remote debugging using localhost:2347
/home/smarchi/src/binutils-gdb/gdb/progspace.h:240: internal-error: set_solib_ops: Assertion `m_solib_ops == nullptr' failed.
The issue is that remote_unpush_target uses
scoped_restore_current_inferior to save the context, which only restores
the current inferior on exit. But it then uses
switch_to_inferior_no_thread, which switches the inferior and the
program space. The program space is therefore left unrestored. This
can leave the current inferior and current program space out of sync.
With two inferiors, let's say we enter with current inferior == 1 and
current program space == 1. When calling switch_to_inferior_no_thread
for inferior 2, we set the current inferior to 2 and current program
space to 2. On exit, only the original inferior is restored, so we end
up with current inferior == 1 and current program space == 2.
The problem can be observed manually by starting two remote inferiors
and disconnecting while inferior 1 is selected:
$ ./gdb -nx --data-directory=data-directory -q \
-ex 'set sysroot /' \
-ex 'target extended-remote | gdbserver --multi --once -' \
-ex 'file /home/smarchi/build/wt/amd/gdb/testsuite/outputs/gdb.server/extended-remote-restart/extended-remote-restart' \
-ex 'set remote exec-file /home/smarchi/build/wt/amd/gdb/testsuite/outputs/gdb.server/extended-remote-restart/extended-remote-restart' \
-ex 'b main' \
-ex r \
-ex 'add-inferior' \
-ex 'inferior 2' \
-ex 'file /home/smarchi/build/wt/amd/gdb/testsuite/outputs/gdb.server/extended-remote-restart/extended-remote-restart' \
-ex 'run' \
-ex 'inferior 1' \
-ex 'disconnect'
Then, connecting top-gdb to that gdb, we see the inconsistency:
(top-gdb) p current_inferior_.m_obj.num
$1 = 1
(top-gdb) p current_program_space.num
$2 = 2
When the test tries to connect to a remote target again, GDB maps the
remote inferior to inferior 1, but tries to set the solib_ops of program
space 2, which already has an solib_ops set, causing the internal error.
Fix this by using scoped_restore_current_program_space in addition to
scoped_restore_current_inferior. With this patch applied, we get:
(top-gdb) p current_inferior_.m_obj.num
$1 = 1
(top-gdb) p current_program_space.num
$2 = 1
With this patch, we then hit another internal error, fixed by the
following patch.
Change-Id: If916f581a223d6611f7f23a9cbbf1825d2cdd0ba
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
Diffstat (limited to 'gdb/common/preprocessor.h')
0 files changed, 0 insertions, 0 deletions