[RFA 14/14] Changes to solib-svr4.c
Gary Benson
gbenson@redhat.com
Thu Jul 11 10:45:00 GMT 2013
This patch modifies svr4_free_so to free the containing so_list
object, and adds the acquire/release logic described in [1].
Note that there is a more programmatic description of this in
the final hunk of this patch.
[1] http://sourceware.org/ml/gdb-patches/2013-07/msg00298.html
-------------- next part --------------
2013-07-10 Gary Benson <gbenson@redhat.com>
* solib-svr4.c (struct lm_info): New fields "copy" and "acquired".
(svr4_free_so): Add acquired copy logic. Free the containing
so_list when freeing is required.
(svr4_copy_library_list): Remove.
(svr4_current_sos): Replace call to svr4_copy_library_list with
acquired copy logic.
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 6f8d0ef..cab46f1 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -72,6 +72,15 @@ struct lm_info
/* Values read in from inferior's fields of the same name. */
CORE_ADDR l_ld, l_next, l_prev, l_name;
+
+ /* A copy of the solib containing this lm_info, if one exists.
+ See comment in svr4_current_sos for more information. */
+ struct so_list *copy;
+
+ /* Nonzero if the solib containing this lm_info is an acquired
+ copy of another solib. See comment in svr4_current_sos for
+ more information. */
+ unsigned int acquired : 1;
};
/* On SVR4 systems, a list of symbols in the dynamic linker where
@@ -1055,7 +1064,29 @@ struct svr4_library_list
static void
svr4_free_so (struct so_list *so)
{
+ if (so->lm_info)
+ {
+ /* If this library is an acquired copy then release it. */
+ if (so->lm_info->acquired)
+ {
+ so->lm_info->acquired = 0;
+ return;
+ }
+
+ /* If the library has an acquired copy then unhook it. */
+ if (so->lm_info->copy && so->lm_info->copy->lm_info->acquired)
+ {
+ so->lm_info->copy->lm_info->acquired = 0;
+ so->lm_info->copy = NULL;
+ }
+
+ /* If the library has an unacquired copy then free it. */
+ if (so->lm_info->copy)
+ svr4_free_so (so->lm_info->copy);
+ }
+
xfree (so->lm_info);
+ xfree (so);
}
/* Implement target_so_ops.clear_so. */
@@ -1083,34 +1114,6 @@ svr4_free_library_list (void *p_list)
}
}
-/* Copy library list. */
-
-static struct so_list *
-svr4_copy_library_list (struct so_list *src)
-{
- struct so_list *dst = NULL;
- struct so_list **link = &dst;
-
- while (src != NULL)
- {
- struct so_list *new;
-
- new = xmalloc (sizeof (struct so_list));
- memcpy (new, src, sizeof (struct so_list));
-
- new->lm_info = xmalloc (sizeof (struct lm_info));
- memcpy (new->lm_info, src->lm_info, sizeof (struct lm_info));
-
- new->next = NULL;
- *link = new;
- link = &new->next;
-
- src = src->next;
- }
-
- return dst;
-}
-
#ifdef HAVE_LIBEXPAT
#include "xml-support.h"
@@ -1470,7 +1473,62 @@ svr4_current_sos (void)
/* If the solib list has been read and stored by the probes
interface then we return a copy of the stored list. */
if (info->solib_list != NULL)
- return svr4_copy_library_list (info->solib_list);
+ {
+ struct so_list *so, *result, **link = &result;
+
+ /* To avoid copying each solib each time the list is updated,
+ we retain pointers to the copies and mark each copy as
+ "acquired" before returning the list to update_solib_list.
+ Then, for each copy:
+
+ - If the solib has already been added to the program space's
+ so_list then update_solib_list will free the copy we
+ returned using free_so. This releases the acquired copy
+ for re-use by the next call to svr4_current_sos.
+
+ - If the solib has not been added to the program space's
+ so_list then update_solib_list will not free the copy we
+ returned. The next call to svr4_current_sos will note that
+ the copy is still acquired and create a fresh copy to
+ return.
+
+ This ensures no solib is copied more than twice. */
+ for (so = info->solib_list; so; so = so->next)
+ {
+ gdb_assert (so->lm_info != NULL);
+
+ /* If the library has an acquired copy then unhook it. */
+ if (so->lm_info->copy && so->lm_info->copy->lm_info->acquired)
+ {
+ so->lm_info->copy->lm_info->acquired = 0;
+ so->lm_info->copy = NULL;
+ }
+
+ /* If this library does not have a copy then create one. */
+ if (so->lm_info->copy == NULL)
+ {
+ struct so_list *copy;
+
+ copy = XZALLOC (struct so_list);
+ memcpy (copy, so, sizeof (struct so_list));
+
+ copy->lm_info = xmalloc (sizeof (struct lm_info));
+ memcpy (copy->lm_info, so->lm_info, sizeof (struct lm_info));
+
+ so->lm_info->copy = copy;
+ }
+
+ /* Mark the copy as acquired and link it into the result. */
+ gdb_assert (!so->lm_info->copy->lm_info->acquired);
+ so->lm_info->copy->lm_info->acquired = 1;
+
+ so->lm_info->copy->next = NULL;
+ *link = so->lm_info->copy;
+ link = &so->lm_info->copy->next;
+ }
+
+ return result;
+ }
/* Otherwise obtain the solib list directly from the inferior. */
return svr4_current_sos_direct (info);
More information about the Gdb-patches
mailing list