]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/solib: use owning_intrusive_list for solib list
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 12 Aug 2024 17:09:05 +0000 (13:09 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Fri, 13 Sep 2024 11:38:56 +0000 (07:38 -0400)
Functions implementing `solib_ops::current_sos` return a list of solib
object, transferring the ownership to their callers.  However, the
return type, `intrusive_list<solib>`, does not reflect that.

Also, some of these functions build these lists incrementally, reading
this from the target for each solib.  If a target read were to throw,
for instance, the already created solibs would just be leaked.

Change `solib_ops::current_sos` to return an owning_intrusive_list to
address that.  Change `program_space::so_list` to be an
owning_intrusive_list as well.  This also saves us doing a few manual
deletes.

Change-Id: I6e4071d49744874491625075136c59cce8e608d4
Reviewed-by: Keith Seitz <keiths@redhat.com>
gdb/progspace.h
gdb/solib-aix.c
gdb/solib-darwin.c
gdb/solib-dsbt.c
gdb/solib-frv.c
gdb/solib-rocm.c
gdb/solib-svr4.c
gdb/solib-target.c
gdb/solib.c
gdb/solist.h

index 82c0a743f3265ee7152fa95f3ed01c3ba49d058f..999e7a39182e82cbf9b7aa46ecba5b292c3e6337 100644 (file)
@@ -289,7 +289,7 @@ struct program_space
   struct objfile *objfile_for_address (CORE_ADDR address);
 
   /* Return the list of  all the solibs in this program space.  */
-  intrusive_list<solib> &solibs ()
+  owning_intrusive_list<solib> &solibs ()
   { return so_list; }
 
   /* Similar to `bfd_get_filename (exec_bfd ())` but in original form given
@@ -399,7 +399,7 @@ struct program_space
 
   /* List of shared objects mapped into this space.  Managed by
      solib.c.  */
-  intrusive_list<solib> so_list;
+  owning_intrusive_list<solib> so_list;
 
   /* Number of calls to solib_add.  */
   unsigned int solib_add_generation = 0;
index 1c319c22223fca4f2242f413fac0836b7a648591..926f1ed766d07df4cbaaf58fa05df8a521dd34e4 100644 (file)
@@ -444,7 +444,7 @@ solib_aix_solib_create_inferior_hook (int from_tty)
 
 /* Implement the "current_sos" solib_ops method.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 solib_aix_current_sos ()
 {
   std::optional<std::vector<lm_info_aix>> &library_list
@@ -452,14 +452,13 @@ solib_aix_current_sos ()
   if (!library_list.has_value ())
     return {};
 
-  intrusive_list<solib> sos;
+  owning_intrusive_list<solib> sos;
 
   /* Build a struct solib for each entry on the list.
      We skip the first entry, since this is the entry corresponding
      to the main executable, not a shared library.  */
   for (int ix = 1; ix < library_list->size (); ix++)
     {
-      solib *new_solib = new solib;
       std::string so_name;
 
       lm_info_aix &info = (*library_list)[ix];
@@ -481,12 +480,11 @@ solib_aix_current_sos ()
                                  info.member_name.c_str ());
        }
 
-      new_solib->so_original_name = so_name;
-      new_solib->so_name = so_name;
-      new_solib->lm_info = std::make_unique<lm_info_aix> (info);
-
       /* Add it to the list.  */
-      sos.push_back (*new_solib);
+      auto &new_solib = sos.emplace_back ();
+      new_solib.so_original_name = so_name;
+      new_solib.so_name = so_name;
+      new_solib.lm_info = std::make_unique<lm_info_aix> (info);
     }
 
   return sos;
index c7a7f6241021feb7257c66f150fcafa145d6b570..6c7d9065a658a6957ac502037a2becb30d462c43 100644 (file)
@@ -212,7 +212,7 @@ open_symbol_file_object (int from_tty)
 
 /* Build a list of currently loaded shared objects.  See solib-svr4.c.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 darwin_current_sos ()
 {
   type *ptr_type
@@ -230,7 +230,7 @@ darwin_current_sos ()
 
   image_info_size = ptr_len * 3;
 
-  intrusive_list<solib> sos;
+  owning_intrusive_list<solib> sos;
 
   /* Read infos for each solib.
      The first entry was rumored to be the executable itself, but this is not
@@ -272,16 +272,15 @@ darwin_current_sos ()
        break;
 
       /* Create and fill the new struct solib element.  */
-      solib *newobj = new solib;
+      auto &newobj = sos.emplace_back ();
 
       auto li = std::make_unique<lm_info_darwin> ();
 
-      newobj->so_name = file_path.get ();
-      newobj->so_original_name = newobj->so_name;
+      newobj.so_name = file_path.get ();
+      newobj.so_original_name = newobj.so_name;
       li->lm_addr = load_addr;
 
-      newobj->lm_info = std::move (li);
-      sos.push_back (*newobj);
+      newobj.lm_info = std::move (li);
     }
 
   return sos;
index 2751ded40c5e9c2aaa68294dce24e8869def0485..360aede8f301d457f066a6958a70711a5dd88ac8 100644 (file)
@@ -512,13 +512,13 @@ lm_base (void)
    themselves.  The declaration of `struct solib' says which fields
    we provide values for.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 dsbt_current_sos (void)
 {
   bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr;
   dsbt_info *info = get_dsbt_info (current_program_space);
-  intrusive_list<solib> sos;
+  owning_intrusive_list<solib> sos;
 
   /* Make sure that the main executable has been relocated.  This is
      required in order to find the address of the global offset table,
@@ -594,7 +594,7 @@ dsbt_current_sos (void)
              break;
            }
 
-         solib *sop = new solib;
+         auto &sop = sos.emplace_back ();
          auto li = std::make_unique<lm_info_dsbt> ();
          li->map = loadmap;
          /* Fetch the name.  */
@@ -612,12 +612,11 @@ dsbt_current_sos (void)
                gdb_printf (gdb_stdlog, "current_sos: name = %s\n",
                            name_buf.get ());
 
-             sop->so_name = name_buf.get ();
-             sop->so_original_name = sop->so_name;
+             sop.so_name = name_buf.get ();
+             sop.so_original_name = sop.so_name;
            }
 
-         sop->lm_info = std::move (li);
-         sos.push_back (*sop);
+         sop.lm_info = std::move (li);
        }
       else
        {
index 2ce35c4bc28f4c968f5abad9153acb85b076bb48..25873e6df60124655fe1602d9a2e0a10e1ea009f 100644 (file)
@@ -306,12 +306,12 @@ lm_base (void)
 
 /* Implement the "current_sos" solib_ops method.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 frv_current_sos ()
 {
   bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr, mgot;
-  intrusive_list<solib> sos;
+  owning_intrusive_list<solib> sos;
 
   /* Make sure that the main executable has been relocated.  This is
      required in order to find the address of the global offset table,
@@ -377,12 +377,12 @@ frv_current_sos ()
              break;
            }
 
-         solib *sop = new solib;
+         auto &sop = sos.emplace_back ();
          auto li = std::make_unique<lm_info_frv> ();
          li->map = loadmap;
          li->got_value = got_addr;
          li->lm_addr = lm_addr;
-         sop->lm_info = std::move (li);
+         sop.lm_info = std::move (li);
 
          /* Fetch the name.  */
          addr = extract_unsigned_integer (lm_buf.l_name,
@@ -397,11 +397,9 @@ frv_current_sos ()
            warning (_("Can't read pathname for link map entry."));
          else
            {
-             sop->so_name = name_buf.get ();
-             sop->so_original_name = sop->so_name;
+             sop.so_name = name_buf.get ();
+             sop.so_original_name = sop.so_name;
            }
-
-         sos.push_back (*sop);
        }
       else
        {
index 9b995c7a3abe511269865022289897dee3e9077c..156b36a42634112797114b159bcecdfd9f08c9a5 100644 (file)
@@ -204,20 +204,18 @@ rocm_solib_handle_event ()
 
 /* Create so_list objects from rocm_so objects in SOS.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
 {
-  intrusive_list<solib> dst;
+  owning_intrusive_list<solib> dst;
 
   for (const rocm_so &so : sos)
     {
-      solib *newobj = new solib;
-      newobj->lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
+      auto &newobj = dst.emplace_back ();
 
-      newobj->so_name = so.name;
-      newobj->so_original_name = so.unique_name;
-
-      dst.push_back (*newobj);
+      newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
+      newobj.so_name = so.name;
+      newobj.so_original_name = so.unique_name;
     }
 
   return dst;
@@ -226,11 +224,11 @@ so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
 /* Build a list of `struct solib' objects describing the shared
    objects currently loaded in the inferior.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 rocm_solib_current_sos ()
 {
   /* First, retrieve the host-side shared library list.  */
-  intrusive_list<solib> sos = svr4_so_ops.current_sos ();
+  owning_intrusive_list<solib> sos = svr4_so_ops.current_sos ();
 
   /* Then, the device-side shared library list.  */
   std::vector<rocm_so> &dev_sos = get_solib_info (current_inferior ())->solib_list;
@@ -238,7 +236,7 @@ rocm_solib_current_sos ()
   if (dev_sos.empty ())
     return sos;
 
-  intrusive_list<solib> dev_so_list = so_list_from_rocm_sos (dev_sos);
+  owning_intrusive_list<solib> dev_so_list = so_list_from_rocm_sos (dev_sos);
 
   if (sos.empty ())
     return dev_so_list;
index 5d232051403ac0ed42d9c424db007ca0ec625bf6..928d6547a32fe7f72e7ae1f611b88a4879edc490 100644 (file)
@@ -991,20 +991,18 @@ svr4_clear_so (const solib &so)
 
 /* Create the so_list objects equivalent to the svr4_sos in SOS.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 so_list_from_svr4_sos (const std::vector<svr4_so> &sos)
 {
-  intrusive_list<solib> dst;
+  owning_intrusive_list<solib> dst;
 
   for (const svr4_so &so : sos)
     {
-      struct solib *newobj = new struct solib;
+      auto &newobj = dst.emplace_back ();
 
-      newobj->so_name = so.name;
-      newobj->so_original_name = so.name;
-      newobj->lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
-
-      dst.push_back (*newobj);
+      newobj.so_name = so.name;
+      newobj.so_original_name = so.name;
+      newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
     }
 
   return dst;
@@ -1184,25 +1182,24 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
 /* If no shared library information is available from the dynamic
    linker, build a fallback list from other sources.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 svr4_default_sos (svr4_info *info)
 {
   if (!info->debug_loader_offset_p)
     return {};
 
-  solib *newobj = new solib;
   auto li = std::make_unique<lm_info_svr4> ();
 
   /* Nothing will ever check the other fields if we set l_addr_p.  */
   li->l_addr = li->l_addr_inferior = info->debug_loader_offset;
   li->l_addr_p = 1;
 
-  newobj->lm_info = std::move (li);
-  newobj->so_name = info->debug_loader_name;
-  newobj->so_original_name = newobj->so_name;
+  owning_intrusive_list<solib> sos;
+  auto &newobj = sos.emplace_back ();
 
-  intrusive_list<solib> sos;
-  sos.push_back (*newobj);
+  newobj.lm_info = std::move (li);
+  newobj.so_name = info->debug_loader_name;
+  newobj.so_original_name = newobj.so_name;
 
   return sos;
 }
@@ -1373,10 +1370,10 @@ svr4_current_sos_direct (struct svr4_info *info)
 
 /* Collect sos read and stored by the probes interface.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 svr4_collect_probes_sos (svr4_info *info)
 {
-  intrusive_list<solib> res;
+  owning_intrusive_list<solib> res;
 
   for (const auto &tuple : info->solib_lists)
     {
@@ -1390,10 +1387,10 @@ svr4_collect_probes_sos (svr4_info *info)
 /* Implement the main part of the "current_sos" solib_ops
    method.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 svr4_current_sos_1 (svr4_info *info)
 {
-  intrusive_list<solib> sos;
+  owning_intrusive_list<solib> sos;
 
   /* If we're using the probes interface, we can use the cache as it will
      be maintained by probe update/reload actions.  */
@@ -1417,11 +1414,11 @@ svr4_current_sos_1 (svr4_info *info)
 
 /* Implement the "current_sos" solib_ops method.  */
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 svr4_current_sos ()
 {
   svr4_info *info = get_svr4_info (current_program_space);
-  intrusive_list<solib> sos = svr4_current_sos_1 (info);
+  owning_intrusive_list<solib> sos = svr4_current_sos_1 (info);
   struct mem_range vsyscall_range;
 
   /* Filter out the vDSO module, if present.  Its symbol file would
@@ -1478,9 +1475,7 @@ svr4_current_sos ()
 
          if (vsyscall_range.contains (li->l_ld))
            {
-             auto next = sos.erase (so);
-             delete &*so;
-             so = next;
+             so = sos.erase (so);
              break;
            }
 
index 3fffa7c25950c3e71107f97f8ffccd12ec96f969..8f73d5df55bddcc32708f7f96f35ae42e0730053 100644 (file)
@@ -226,10 +226,10 @@ solib_target_parse_libraries (const char *library)
 }
 #endif
 
-static intrusive_list<solib>
+static owning_intrusive_list<solib>
 solib_target_current_sos (void)
 {
-  intrusive_list<solib> sos;
+  owning_intrusive_list<solib> sos;
 
   /* Fetch the list of shared libraries.  */
   std::optional<gdb::char_vector> library_document
@@ -245,15 +245,12 @@ solib_target_current_sos (void)
   /* Build a struct solib for each entry on the list.  */
   for (lm_info_target_up &info : library_list)
     {
-      solib *new_solib = new solib;
+      auto &new_solib = sos.emplace_back ();
 
       /* We don't need a copy of the name in INFO anymore.  */
-      new_solib->so_name = std::move (info->name);
-      new_solib->so_original_name = new_solib->so_name;
-      new_solib->lm_info = std::move (info);
-
-      /* Add it to the list.  */
-      sos.push_back (*new_solib);
+      new_solib.so_name = std::move (info->name);
+      new_solib.so_original_name = new_solib.so_name;
+      new_solib.lm_info = std::move (info);
     }
 
   return sos;
index b123be302bc3dea8373841fe89e1607ba8b0101e..5c926def715080f3ab54172afcabc3361f15ceb0 100644 (file)
@@ -755,8 +755,8 @@ update_solib_list (int from_tty)
      the time we're done walking GDB's list, the inferior's list
      contains only the new shared objects, which we then add.  */
 
-  intrusive_list<solib> inferior = ops->current_sos ();
-  intrusive_list<solib>::iterator gdb_iter
+  owning_intrusive_list<solib> inferior = ops->current_sos ();
+  owning_intrusive_list<solib>::iterator gdb_iter
     = current_program_space->so_list.begin ();
   while (gdb_iter != current_program_space->so_list.end ())
     {
@@ -785,7 +785,6 @@ update_solib_list (int from_tty)
       if (inferior_iter != inferior.end ())
        {
          inferior.erase (inferior_iter);
-         delete &*inferior_iter;
          ++gdb_iter;
        }
 
@@ -798,9 +797,6 @@ update_solib_list (int from_tty)
 
          current_program_space->deleted_solibs.push_back (gdb_iter->so_name);
 
-         intrusive_list<solib>::iterator gdb_iter_next
-           = current_program_space->so_list.erase (gdb_iter);
-
          /* Unless the user loaded it explicitly, free SO's objfile.  */
          if (gdb_iter->objfile != nullptr
              && !(gdb_iter->objfile->flags & OBJF_USERLOADED)
@@ -811,8 +807,7 @@ update_solib_list (int from_tty)
             sections from so.abfd; remove them.  */
          current_program_space->remove_target_sections (&*gdb_iter);
 
-         delete &*gdb_iter;
-         gdb_iter = gdb_iter_next;
+         gdb_iter = current_program_space->so_list.erase (gdb_iter);
        }
     }
 
@@ -1151,11 +1146,13 @@ clear_solib (program_space *pspace)
 
   disable_breakpoints_in_shlibs (pspace);
 
-  pspace->so_list.clear_and_dispose ([pspace] (solib *so) {
-    notify_solib_unloaded (pspace, *so);
-    pspace->remove_target_sections (so);
-    delete so;
-  });
+  for (solib &so : pspace->so_list)
+    {
+      notify_solib_unloaded (pspace, so);
+      pspace->remove_target_sections (&so);
+    };
+
+  pspace->so_list.clear ();
 
   if (ops->clear_solib != nullptr)
     ops->clear_solib (pspace);
index b898ae318999d16f4b9ab0cd196e56dac3164f45..336bb011b2e07851226aee77919bcc091303c7ae 100644 (file)
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512      /* FIXME: Should be dynamic */
+
 /* For domain_enum domain.  */
 #include "symtab.h"
 #include "gdb_bfd.h"
+#include "gdbsupport/owning_intrusive_list.h"
 #include "target-section.h"
 
 /* Base class for target-specific link map information.  */
@@ -119,7 +121,7 @@ struct solib_ops
      inferior --- we don't examine any of the shared library files
      themselves.  The declaration of `struct solib' says which fields
      we provide values for.  */
-  intrusive_list<solib> (*current_sos) ();
+  owning_intrusive_list<solib> (*current_sos) ();
 
   /* Find, open, and read the symbols for the main executable.  If
      FROM_TTY is non-zero, allow messages to be printed.  */