mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 09:08:59 +00:00
gdb: remove the pop_all_targets (and friends) global functions
This commit removes the global functions pop_all_targets, pop_all_targets_above, and pop_all_targets_at_and_above, and makes them methods on the inferior class. As the pop_all_targets functions will unpush each target, which decrements the targets reference count, it is possible that the target might be closed. Right now, closing a target, in some cases, depends on the current inferior being set correctly, that is, to the inferior from which the target was popped. To facilitate this I have used switch_to_inferior_no_thread within the new methods. Previously it was the responsibility of the caller to ensure that the correct inferior was selected. In a couple of places (event-top.c and top.c) I have been able to remove a previous switch_to_inferior_no_thread call. In remote_unpush_target (remote.c) I have left the switch_to_inferior_no_thread call as it is required for the generic_mourn_inferior call.
This commit is contained in:
@@ -1293,10 +1293,9 @@ async_disconnect (gdb_client_data arg)
|
||||
|
||||
for (inferior *inf : all_inferiors ())
|
||||
{
|
||||
switch_to_inferior_no_thread (inf);
|
||||
try
|
||||
{
|
||||
pop_all_targets ();
|
||||
inf->pop_all_targets ();
|
||||
}
|
||||
catch (const gdb_exception &exception)
|
||||
{
|
||||
|
||||
@@ -103,6 +103,48 @@ inferior::unpush_target (struct target_ops *t)
|
||||
return m_target_stack.unpush (t);
|
||||
}
|
||||
|
||||
/* See inferior.h. */
|
||||
|
||||
void
|
||||
inferior::unpush_target_and_assert (struct target_ops *target)
|
||||
{
|
||||
gdb_assert (current_inferior () == this);
|
||||
|
||||
if (!unpush_target (target))
|
||||
internal_error ("pop_all_targets couldn't find target %s\n",
|
||||
target->shortname ());
|
||||
}
|
||||
|
||||
/* See inferior.h. */
|
||||
|
||||
void
|
||||
inferior::pop_all_targets_above (enum strata stratum)
|
||||
{
|
||||
/* Unpushing a target might cause it to close. Some targets currently
|
||||
rely on the current_inferior being set for their ::close method, so we
|
||||
temporarily switch inferior now. */
|
||||
scoped_restore_current_pspace_and_thread restore_pspace_and_thread;
|
||||
switch_to_inferior_no_thread (this);
|
||||
|
||||
while (top_target ()->stratum () > stratum)
|
||||
unpush_target_and_assert (top_target ());
|
||||
}
|
||||
|
||||
/* See inferior.h. */
|
||||
|
||||
void
|
||||
inferior::pop_all_targets_at_and_above (enum strata stratum)
|
||||
{
|
||||
/* Unpushing a target might cause it to close. Some targets currently
|
||||
rely on the current_inferior being set for their ::close method, so we
|
||||
temporarily switch inferior now. */
|
||||
scoped_restore_current_pspace_and_thread restore_pspace_and_thread;
|
||||
switch_to_inferior_no_thread (this);
|
||||
|
||||
while (top_target ()->stratum () >= stratum)
|
||||
unpush_target_and_assert (top_target ());
|
||||
}
|
||||
|
||||
void
|
||||
inferior::set_tty (std::string terminal_name)
|
||||
{
|
||||
|
||||
@@ -398,6 +398,22 @@ public:
|
||||
target_ops *top_target ()
|
||||
{ return m_target_stack.top (); }
|
||||
|
||||
/* Unpush all targets except the dummy target from m_target_stack. As
|
||||
targets are removed from m_target_stack their reference count is
|
||||
decremented, which may cause a target to close. */
|
||||
void pop_all_targets ()
|
||||
{ pop_all_targets_above (dummy_stratum); }
|
||||
|
||||
/* Unpush all targets above STRATUM from m_target_stack. As targets are
|
||||
removed from m_target_stack their reference count is decremented,
|
||||
which may cause a target to close. */
|
||||
void pop_all_targets_above (enum strata stratum);
|
||||
|
||||
/* Unpush all targets at and above STRATUM from m_target_stack. As
|
||||
targets are removed from m_target_stack their reference count is
|
||||
decremented, which may cause a target to close. */
|
||||
void pop_all_targets_at_and_above (enum strata stratum);
|
||||
|
||||
/* Return the target at process_stratum level in this inferior's
|
||||
target stack. */
|
||||
struct process_stratum_target *process_target ()
|
||||
@@ -616,6 +632,10 @@ public:
|
||||
registry<inferior> registry_fields;
|
||||
|
||||
private:
|
||||
|
||||
/* Unpush TARGET and assert that it worked. */
|
||||
void unpush_target_and_assert (struct target_ops *target);
|
||||
|
||||
/* The inferior's target stack. */
|
||||
target_stack m_target_stack;
|
||||
|
||||
|
||||
@@ -5717,7 +5717,7 @@ remote_unpush_target (remote_target *target)
|
||||
for (inferior *inf : all_inferiors (target))
|
||||
{
|
||||
switch_to_inferior_no_thread (inf);
|
||||
pop_all_targets_at_and_above (process_stratum);
|
||||
inf->pop_all_targets_at_and_above (process_stratum);
|
||||
generic_mourn_inferior ();
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ struct scoped_mock_context
|
||||
~scoped_mock_context ()
|
||||
{
|
||||
inferior_list.erase (inferior_list.iterator_to (mock_inferior));
|
||||
pop_all_targets_at_and_above (process_stratum);
|
||||
mock_inferior.pop_all_targets_at_and_above (process_stratum);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
40
gdb/target.c
40
gdb/target.c
@@ -1245,44 +1245,6 @@ target_stack::unpush (target_ops *t)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Unpush TARGET and assert that it worked. */
|
||||
|
||||
static void
|
||||
unpush_target_and_assert (struct target_ops *target)
|
||||
{
|
||||
if (!current_inferior ()->unpush_target (target))
|
||||
{
|
||||
gdb_printf (gdb_stderr,
|
||||
"pop_all_targets couldn't find target %s\n",
|
||||
target->shortname ());
|
||||
internal_error (_("failed internal consistency check"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pop_all_targets_above (enum strata above_stratum)
|
||||
{
|
||||
while ((int) (current_inferior ()->top_target ()->stratum ())
|
||||
> (int) above_stratum)
|
||||
unpush_target_and_assert (current_inferior ()->top_target ());
|
||||
}
|
||||
|
||||
/* See target.h. */
|
||||
|
||||
void
|
||||
pop_all_targets_at_and_above (enum strata stratum)
|
||||
{
|
||||
while ((int) (current_inferior ()->top_target ()->stratum ())
|
||||
>= (int) stratum)
|
||||
unpush_target_and_assert (current_inferior ()->top_target ());
|
||||
}
|
||||
|
||||
void
|
||||
pop_all_targets (void)
|
||||
{
|
||||
pop_all_targets_above (dummy_stratum);
|
||||
}
|
||||
|
||||
void
|
||||
target_unpusher::operator() (struct target_ops *ops) const
|
||||
{
|
||||
@@ -2539,7 +2501,7 @@ target_preopen (int from_tty)
|
||||
it doesn't (which seems like a win for UDI), remove it now. */
|
||||
/* Leave the exec target, though. The user may be switching from a
|
||||
live process to a core of the same program. */
|
||||
pop_all_targets_above (file_stratum);
|
||||
current_inferior ()->pop_all_targets_above (file_stratum);
|
||||
|
||||
target_pre_inferior (from_tty);
|
||||
}
|
||||
|
||||
11
gdb/target.h
11
gdb/target.h
@@ -2389,17 +2389,6 @@ extern void target_pre_inferior (int);
|
||||
|
||||
extern void target_preopen (int);
|
||||
|
||||
/* Does whatever cleanup is required to get rid of all pushed targets. */
|
||||
extern void pop_all_targets (void);
|
||||
|
||||
/* Like pop_all_targets, but pops only targets whose stratum is at or
|
||||
above STRATUM. */
|
||||
extern void pop_all_targets_at_and_above (enum strata stratum);
|
||||
|
||||
/* Like pop_all_targets, but pops only targets whose stratum is
|
||||
strictly above ABOVE_STRATUM. */
|
||||
extern void pop_all_targets_above (enum strata above_stratum);
|
||||
|
||||
extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
|
||||
CORE_ADDR offset);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user