This is the mail archive of the gdb-patches@sources.redhat.com 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]

[rfa] remote SVR4 shared libraries vs. reattaching


Suppose that we connect to a remote target, and start debugging some problem
in a user application via gdbserver.  For whatever reason, GDB gets
confused, and we need to exit it (cleanly, removing breakpoints - without
that there's nothing we can do).  Or perhaps we want to switch hosts, or
anything along these lines.  Seems reasonable, yes?  I've found myself doing
this quite a lot.

So, gdbserver sits and waits for us to reattach.  We reconnect, we trigger
SOLIB_CREATE_INFERIOR_HOOK (), and we promptly assume that whatever PC we
stopped at must be the first instruction of the dynamic loader.  Symbol
resolution gets a little confused at this point.

There's nothing we can reliably do about this (short of comparing a few
instructions with the beginning of the .text segment of the dynamic loader,
which is overkill, IMHO) if we were debugging the loader.  But if we were
off in application land, then _DYNAMIC has useful information now - like
the start address of the dynamic loader.  Which is all we wanted in the
first place.

[As an aside, I seem to recall from when I last looked at this that a lot of
the other shared library packages have similar problems.  Basically, if
!SVR4_SHARED_LIBRARIES, creating the inferior hook at a random point in time
is quite unlikely to work...]

Does this patch look OK?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2001-08-07  Daniel Jacobowitz  <drow@mvista.com>

	* solib-svr4.c (enable_break): Check the inferior link map
	before assuming the inferior PC is at the start of the dynamic
	loader.

Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.16
diff -u -p -r1.16 solib-svr4.c
--- solib-svr4.c	2001/07/02 19:37:59	1.16
+++ solib-svr4.c	2001/08/07 18:41:45
@@ -1198,7 +1198,9 @@ enable_break (void)
     {
       unsigned int interp_sect_size;
       char *buf;
-      CORE_ADDR load_addr;
+      CORE_ADDR load_addr = 0;
+      int load_addr_found = 0;
+      struct so_list *inferior_sos;
       bfd *tmp_bfd = NULL;
       int tmp_fd = -1;
       char *tmp_pathname = NULL;
@@ -1235,10 +1237,30 @@ enable_break (void)
 	  goto bkpt_at_symbol;
 	}
 
-      /* We find the dynamic linker's base address by examining the
-         current pc (which point at the entry point for the dynamic
-         linker) and subtracting the offset of the entry point.  */
-      load_addr = read_pc () - tmp_bfd->start_address;
+      /* If the entry in _DYNAMIC for the dynamic linker has already
+         been filled in, we can read its base address from there. */
+      inferior_sos = svr4_current_sos ();
+      if (inferior_sos)
+	{
+	  /* Connected to a running target.  Update our shared library table. */
+	  solib_add (NULL, 0, NULL);
+	}
+      while (inferior_sos)
+	{
+	  if (!strcmp (buf, inferior_sos->so_original_name))
+	    {
+	      load_addr_found = 1;
+	      load_addr = LM_ADDR (inferior_sos);
+	      break;
+	    }
+	  inferior_sos = inferior_sos->next;
+	}
+
+      /* Otherwise we find the dynamic linker's base address by examining
+	 the current pc (which should point at the entry point for the
+	 dynamic linker) and subtracting the offset of the entry point.  */
+      if (!load_addr_found)
+	load_addr = read_pc () - tmp_bfd->start_address;
 
       /* Record the relocated start and end address of the dynamic linker
          text and plt section for svr4_in_dynsym_resolve_code.  */


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