This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Handle solaris dynamic linker name change.


As reported by Joel in http://www.cygwin.com/ml/gdb/2007-03/msg00160.html,
on Solaris, the name of dynamic linker as seen by GDB changes midway.
As result, GDB concludes that dynamic linker was unloaded. Now, after
my breakpoint changes this actually has the effect of breaking pending
breakpoints -- because when GDB decides that dynamic linker is
unloaded, it disables the bp_shlib_event breakpoint, and it's never 
enabled back.

In past gdb version, when infrun.c handles BPSTAT_WHAT_CHECK_SHLIBS
it does:

        solib_add
                which calls update_solib_list
        re_enable_breakpoints_in_shlibs

The re_enable_breakpoint_in_shlibs looks at all breakpoints, and
enables back those which are in mapped shared libs.

In current gdb, the re_enable_breakpoints_in_shlibs code is
just not present. And breakpoint_re_set_one explicitly does
nothing about bpstat_shlib_event.

The solutions are:
1. Stop gdb from thinking dynamic linker was unloaded
2. Revive re_enable_breakpoints_in_shlibs
3. Make breakpoint_re_set one try to re-enable bp_shlib_event

I think (1) is best, since it will make (2) or (3) unnecessary.
The attached patch does (1) by just special casing the names of
libraries. A better approach would be to also make sure address
ranges of libraries are the same, but it would require rearranging 
the code a bit -- quite a bit. OK?

- Volodya

	Ignore change in name of dynamic linker during
	execution.  This also unbreaks pending breakpoints.
	* solist.h (struct target_so_ops): New field
	same.
	* solib-svr4.c (svr4_same): New.
	(_initialize_svr4_solib): Register svr4_same.
	* solib.c (update_solib_list): Use ops->same,
	if available.
---
 gdb/solib-svr4.c |   21 +++++++++++++++++++++
 gdb/solib.c      |   12 ++++++++++--
 gdb/solist.h     |    4 ++++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 1d2737a..d227d32 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1569,6 +1569,26 @@ elf_lookup_lib_symbol (const struct objfile *objfile,
 		(objfile, name, linkage_name, domain, symtab);
 }
 
+static int
+svr4_same (struct so_list *gdb, struct so_list *inferior)
+{
+  if (! strcmp (gdb->so_original_name, inferior->so_original_name))
+    return 1;
+
+  /* On Solaris, when starting inferior we think that
+     dynamic linker is /usr/lib/ld.so.1, but later on,
+     the table of loaded shared libraries contains
+     /lib/ld.so.1.
+     Sometimes one file is a link to another, but sometimes
+     they have identical content, but are not linked to each
+     other.  */
+  if (strcmp (gdb->so_original_name, "/usr/lib/ld.so.1") == 0
+      && strcmp (inferior->so_original_name, "/lib/ld.so.1") == 0)
+    return 1;
+
+  return 0;
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1585,4 +1605,5 @@ _initialize_svr4_solib (void)
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
   svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
+  svr4_so_ops.same = svr4_same;
 }
diff --git a/gdb/solib.c b/gdb/solib.c
index 0ec0a51..d52852a 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -537,8 +537,16 @@ update_solib_list (int from_tty, struct target_ops *target)
 	 the inferior's current list.  */
       while (i)
 	{
-	  if (! strcmp (gdb->so_original_name, i->so_original_name))
-	    break;
+	  if (ops->same)
+	    {
+	      if (ops->same (gdb, i))
+		break;
+	    }
+	  else
+	    {
+	      if (! strcmp (gdb->so_original_name, i->so_original_name))
+		break;	      
+	    }
 
 	  i_link = &i->next;
 	  i = *i_link;
diff --git a/gdb/solist.h b/gdb/solist.h
index 279f1ad..18c547a 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -115,6 +115,10 @@ struct target_so_ops
 						 const domain_enum domain,
 						 struct symtab **symtab);
 
+    /* Given two so_list, first from GDB thread list and another
+       present in the list returned by current_sos, return 1 if
+       they are equal -- referring to the same library.  */
+    int (*same) (struct so_list *gdb, struct so_list *inferior);
   };
 
 /* Free the memory associated with a (so_list *).  */
-- 
1.5.3.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]