]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
Fix crash if connection drops in scoped_restore_current_thread's ctor, part 2
authorPedro Alves <pedro@palves.net>
Tue, 7 Jul 2020 00:50:10 +0000 (01:50 +0100)
committerPedro Alves <palves@redhat.com>
Wed, 8 Jul 2020 23:29:08 +0000 (00:29 +0100)
commit1ad36a4b892fc4425d6f24c298713eeafece7b04
treecfccd931e80a727c8862a1992dcbb3e17402f025
parent84c63c819e4b96d218ac7ba289ad0bbfa56cbd64
Fix crash if connection drops in scoped_restore_current_thread's ctor, part 2

Running the testsuite against an Asan-enabled build of GDB makes
gdb.base/multi-target.exp expose this bug.

scoped_restore_current_thread's ctor calls get_frame_id to record the
selected frame's ID to restore later.  If the frame ID hasn't been
computed yet, it will be computed on the spot, and that will usually
require accessing the target's memory and registers.  If the remote
connection closes, while we're computing the frame ID, the remote
target exits its inferiors, unpushes itself, and throws a
TARGET_CLOSE_ERROR error.  Exiting the inferiors deletes the
inferior's threads.

scoped_restore_current_thread increments the current thread's refcount
to prevent the thread from being deleted from under its feet.
However, the code that does that isn't considering the case of the
thread being deleted from within get_frame_id.  It only increments the
refcount _after_ get_frame_id returns.  So if the current thread is
indeed deleted, the

     tp->incref ();

statement references a stale TP pointer.

Incrementing the refcounts earlier fixes it.

We should probably also let the TARGET_CLOSE_ERROR error propagate in
this case.  That alone would fix it, though it seems better to tweak
the refcount handling too.

gdb/ChangeLog:

* thread.c
(scoped_restore_current_thread::scoped_restore_current_thread):
Incref the thread before calling get_frame_id instead of after.
Let TARGET_CLOSE_ERROR propagate.
gdb/thread.c