This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: gdb doesn't work very well with dynamic linked binaries
- To: drepper at cygnus dot com (Ulrich Drepper), Daniel Berlin <dan at cgsoftware dot com>
- Subject: Re: gdb doesn't work very well with dynamic linked binaries
- From: Kevin Buettner <kevinb at cygnus dot com>
- Date: Tue, 5 Sep 2000 19:12:34 -0700
- Cc: Mark Kettenis <kettenis at wins dot uva dot nl>, hjl at lucon dot org, amylaar at cygnus dot co dot uk, gdb at sourceware dot cygnus dot com
- References: <Pine.LNX.4.21.0009041104140.3814-100000@propylaea.anduin.com> <m33djg81kh.fsf@otr.mynet.cygnus.com>
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