gdb: ensure all targets are popped before an inferior is destructed

Now that the inferiors target_stack automatically manages target
reference counts, we might think that we don't need to unpush targets
when an inferior is deleted...

...unfortunately that is not the case.  The inferior::unpush function
can do some work depending on the type of target, so it is important
that we still pass through this function.

To ensure that this is the case, in this commit I've added an assert
to inferior::~inferior that ensures the inferior's target_stack is
empty (except for the ever present dummy_target).

I've then added a pop_all_targets call to delete_inferior, otherwise
the new assert will fire in, e.g. the gdb.python/py-inferior.exp test.
This commit is contained in:
Andrew Burgess 2022-09-22 18:11:30 +01:00
parent c8181f706f
commit 740a579fd5

View File

@ -70,6 +70,15 @@ inferior::~inferior ()
{
inferior *inf = this;
/* Before the inferior is deleted, all target_ops should be popped from
the target stack, this leaves just the dummy_target behind. If this
is not done, then any target left in the target stack will be left
with an artificially high reference count. As the dummy_target is
still on the target stack then we are about to loose a reference to
that target, leaving its reference count artificially high. However,
this is not critical as the dummy_target is a singleton. */
gdb_assert (m_target_stack.top ()->stratum () == dummy_stratum);
m_continuations.clear ();
target_desc_info_free (inf->tdesc_info);
}
@ -233,6 +242,12 @@ delete_inferior (struct inferior *inf)
gdb::observers::inferior_removed.notify (inf);
/* Pop all targets now, this ensures that inferior::unpush is called
correctly. As pop_all_targets ends up making a temporary switch to
inferior INF then we need to make this call before we delete the
program space, which we do below. */
inf->pop_all_targets ();
/* If this program space is rendered useless, remove it. */
if (inf->pspace->empty ())
delete inf->pspace;