This is the mail archive of the gdb@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]

Re: gdb doesn't work very well with dynamic linked binaries


On Sep 4, 11:16am, Ulrich Drepper wrote:

> > i forwarded them along to various gdb people, but the consensus was
> > that it didn't actually fix the real problem.
> 
> Well, then fix it correctly.  I'm using the patches for years without
> experiencing negative side effects.  Only with them is it possible to
> debug ld.so.

I took a look at these patches in late July in the hope that they
would fix some problems that I was seeing (on a not-to-be-named
platform) with relocating the main executable.  Below is a portion of
a message that I sent to one of the internal Red Hat lists concerning
Uli's solib.c patches.  In order to make sense of some of my comments,
it helps to know that I needed the read-only and read/write sections
to be relocated by different amounts.  This isn't terribly relevant
for the discussion at hand, but I think that any solution we come
up with needs to handle this case.  (My comments immediately preceding
Uli's patch *are* relevant though.)

......................................................................

I tried them and they didn't work for me.  There are several problems
with these patches for my situation:

    1)  The exec_bfd isn't marked DYNAMIC.  (But the OS is relocating
	it anyway; according to the ABI, this is okay.) Anyway, since
	it isn't marked DYNAMIC, Uli's code for relocating the symbols
	doesn't get a chance to run.

    2)  The stop_pc when this code is hit is at the _start symbol in
        the dynamic linker.  But I want to relocate the main executable
	whose _start symbol hasn't been hit yet.

    3)  Even if the preceding two problems could be reconciled, the
        .text and .data sections need to be relocated by different
	amounts.

[...]

I'm going to back out Uli's patch from my sandbox.  It didn't build
cleanly in my sandbox, so I'm posting below a cleaned up version which
does build.  We'll need to incorporate something like this into gdb at
some point.  Before we do though, I'd like to understand why the
changes to breakpoint.c are necessary.  Also, we need to consider the
situation where exec_bfd is not the dynamic linker, but is marked
DYNAMIC for some reason.  If this should happen, Uli's code will get
hit and the symbols in exec_bfd / symfile_objfile will get improperly
relocated.

Index: solib.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/solib.c,v
retrieving revision 1.146
diff -u -p -r1.146 solib.c
--- solib.c	2000/05/28 01:25:33	1.146
+++ solib.c	2000/07/26 17:50:36
@@ -54,6 +54,7 @@
 #include "environ.h"
 #include "language.h"
 #include "gdbcmd.h"
+#include "objfiles.h"
 
 #define MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
 
@@ -1984,6 +1985,39 @@ solib_create_inferior_hook ()
     {
       warning ("shared library handler failed to enable breakpoint");
       return;
+    }
+
+  if ((bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0
+      && bfd_get_start_address (exec_bfd) != stop_pc)
+    {
+      /* We have to relocate the debug information.  */
+      static CORE_ADDR last_displacement;
+      CORE_ADDR displacement = stop_pc - exec_bfd->start_address;
+
+      if (last_displacement != displacement)
+	{
+	  CORE_ADDR correction = displacement - last_displacement;
+	  struct section_offsets *new_offsets;
+	  int i;
+
+	  new_offsets = alloca (symfile_objfile->num_sections
+				* sizeof (*new_offsets));
+
+	  for (i = 0; i < symfile_objfile->num_sections; ++i)
+	    ANOFFSET (new_offsets, i) =
+	      ANOFFSET (symfile_objfile->section_offsets, i);
+
+	  ANOFFSET (new_offsets, SECT_OFF_TEXT (symfile_objfile)) += displacement;
+	  ANOFFSET (new_offsets, SECT_OFF_DATA (symfile_objfile)) += displacement;
+	  ANOFFSET (new_offsets, SECT_OFF_BSS (symfile_objfile)) += displacement;
+	  ANOFFSET (new_offsets, SECT_OFF_RODATA (symfile_objfile)) += displacement;
+
+	  objfile_relocate (symfile_objfile, new_offsets);
+	  breakpoint_re_set ();
+
+	  /* Remember the current displacement.  */
+	  last_displacement = displacement;
+	}
     }
 
 #if !defined(SVR4_SHARED_LIBS) || defined(_SCO_DS)
Index: breakpoint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/breakpoint.c,v
retrieving revision 1.294
diff -u -p -r1.294 breakpoint.c
--- breakpoint.c	2000/06/04 00:35:16	1.294
+++ breakpoint.c	2000/07/26 17:50:44
@@ -7108,6 +7108,7 @@ breakpoint_re_set_one (bint)
       return 0;
     case bp_breakpoint:
     case bp_hardware_breakpoint:
+    case bp_shlib_event:
     case bp_catch_load:
     case bp_catch_unload:
       if (b->addr_string == NULL)
@@ -7246,10 +7247,6 @@ breakpoint_re_set_one (bint)
 
       /* This breakpoint is special, it's set up when the inferior
          starts and we really don't want to touch it.  */
-    case bp_shlib_event:
-
-      /* Like bp_shlib_event, this breakpoint type is special.
-	 Once it is set up, we do not want to touch it.  */
     case bp_thread_event:
 
       /* Keep temporary breakpoints, which can be encountered when we step




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