gdb: remove the pop_all_targets (and friends) global functions
authorAndrew Burgess <aburgess@redhat.com>
Thu, 22 Sep 2022 11:22:22 +0000 (12:22 +0100)
committerAndrew Burgess <aburgess@redhat.com>
Wed, 14 Dec 2022 13:57:22 +0000 (13:57 +0000)
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.

gdb/event-top.c
gdb/inferior.c
gdb/inferior.h
gdb/remote.c
gdb/scoped-mock-context.h
gdb/target.c
gdb/target.h
gdb/top.c

index 29dd151f0b5a40c6452f9d03cbd10939c9defb4c..bcf80bbd7d0b987bb26713db649d6d2345a0af85 100644 (file)
@@ -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)
        {
index 23cbfd63bde0823f414c2c331750df420306c5f8..683e8952d002f178a1649859221cca58e912a1bc 100644 (file)
@@ -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)
 {
index 6fc0a30b12cbb86358c1730c27f3463cd8fabf0f..8a5339713a49ecea238fa23241a6b967469cfd93 100644 (file)
@@ -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;
 
index 614ee069a31909c0d3c08607186b863a1993cd38..ea968ee0c59ae6c3e561e31e7296ef23f7c40345 100644 (file)
@@ -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 ();
     }
 
index a9895303015ea320b319a18be13e90ee0aafa11a..87c1df0d2061aabb8be18bf9c42b49943b98a419 100644 (file)
@@ -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);
   }
 };
 
index 417d384a67ea3cd6c3888f8fff3e76511be7c62f..b7cd3b9b454d997ae1531b16f0268b6270d0bc7e 100644 (file)
@@ -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);
 }
index 68446a39c1b457b79249452312e24132e9eeb6c4..547ee8a3bbda3f1f3181f46aa72db8b92468d449 100644 (file)
@@ -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);
 
index 742997808bd93a76656663fcd4f7d4b85a0aa678..e0e7e48cf7ca23fbe2cdcb173e2daffbc666e8ff 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1855,10 +1855,9 @@ quit_force (int *exit_arg, int from_tty)
      them all out.  */
   for (inferior *inf : all_inferiors ())
     {
-      switch_to_inferior_no_thread (inf);
       try
        {
-         pop_all_targets ();
+         inf->pop_all_targets ();
        }
       catch (const gdb_exception &ex)
        {