public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Mathieu Lacage <mathieu.lacage@gmail.com>
To: Tom Tromey <tromey@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: impossible to resolve symbols in same binary loaded twice with 	dlmopen
Date: Fri, 09 Jul 2010 11:37:00 -0000	[thread overview]
Message-ID: <AANLkTikX8KmJl6_gcsIEWfuJ5m3NS0LHvEZPVuS2iAJ4@mail.gmail.com> (raw)
In-Reply-To: <m3zky14sw5.fsf@fleche.redhat.com>

On Thu, Jul 8, 2010 at 10:31 PM, Tom Tromey <tromey@redhat.com> wrote:

> First, I'm curious: does gdb detect dlmopen calls automatically?  I

Not with the libc implementation of dlmopen.

> thought there was some missing glibc feature here.  I haven't looked

The proper way to handle multiple namespaces in the dynamic loader
would be to use an implementation of the librtld_db.so solaris library
and modify gdb to use it. However, glibc does not provide such an
implementation to encapsulate the details of the loader data
structures.

> into it too much since I wasn't aware of anybody really using dlmopen.
> If gdb cannot do this, please file a bug report.

I do not believe that gdb can do this and I could file a bug but it's
probably going to be hard to fix (beyond my own abilities).

> I am not completely sure that this patch is sufficient.

It's sufficient for me because I use a dynamic loader that has a
different implementation of dlmopen:
  i. there is no compile-time bound on the number of namespaces which
can be created (i.e., the glibc has a 16 or 32 static upper bound)
  ii. there is extra API to be able to create a namespace
independently from loading a binary and extra API to specify some
redirections (say, map libc.so.6 to libc-ns3.so): it's an easy-to-use
API compared to using an audit library
  iii. there is extra API to shutdown a namespace without having to
invoke the destructors of the binaries loaded in it (important to
allow the main process to be shielded from the namespaces)
  iv. the linkmap exported to the debugger contains the binaries of
_all_ the binaries loaded in all namespaces. The loader is careful to
still resolve symbols correctly within each namespace but the linkmap
exported to the debugger contains all binaries to allow gdb to find
all binaries and put breakpoints in them without having to know about
the namespaces.

However, as a disclaimer, the patch I posted and the associated bug
report have been tested on a libc-based system.

> It doesn't seem like it would handle PIE properly.  I think you would
> have to modify objfile_relocate as well.

I am not sure I follow you. I have been using this code with PIEs
(with my other loader, arguably) and have been able to debug stuff.
What symptom do you have in mind ?

> I was wondering if there is a possible bug with a program dlmopen()ing
> itself, but after thinking about it my guess is no.

I don't see any problem with this but I did not test it. Will do so.

> Once you have this patch, does it really work?  It seems like it would
> work ok for some things, like backtraces, but not other things.  E.g.,
> does symbol lookup work properly in the dlmopen case?  I would imagine
> that it does or does not depending on the ordering of objfiles in gdb's
> internal list.

If you use the libc loader and run the test program I attached to the
bug report, you will see that it's indeed impossible to put a
breakpoint or print the address of a function located in a binary
loaded with dlmopen (LD_ID_NEWLM) because gdb is not notified of the
existence of the binaries loaded with dlmopen (and if you inspect the
inferior's linkmap through the _r_debug variable by hand as show
below, you can see that it really does not contain them). It works
fine with my loader though (for the reasons I outlined above).

I would be happy to do more work if needed to satisfy the needs of gdb
on top of the libc dlmopen (even though I am not going to use it): do
you have a specific idea of how you would like this to be done ?

Mathieu

[sample gdb session]
Breakpoint 1, main (argc=2, argv=0x7fffffffe158) at test.c:14
14	  bool doA = true;
(gdb) n
15	  if (strcmp (argv[1], "a") == 0)
(gdb)
17	      doA = true;
(gdb)
23	  void *a = dlmopen (LM_ID_NEWLM, "./libtest.so", RTLD_LAZY);
(gdb)
24	  void *b = dlmopen (LM_ID_NEWLM, "./libtest.so", RTLD_LAZY);
(gdb)
26	  if (doA)
(gdb) p _r_debug.r_map
$6 = (struct link_map_public *) 0x37fa61f0e8
(gdb) p *_r_debug.r_map
$7 = {l_addr = 0, l_name = 0x37fa419614 "", l_ld = 0x600948, l_next =
0x37fa61f678, l_prev = 0x0}
(gdb) p *_r_debug.r_map->l_next
$8 = {l_addr = 140737363566592, l_name = 0x37fa419614 "", l_ld =
0x7ffff7ffe580,
  l_next = 0x7ffff7ffd658, l_prev = 0x37fa61f0e8}
(gdb) p *_r_debug.r_map->l_next->l_next
$9 = {l_addr = 0, l_name = 0x7ffff7ffd640 "/lib64/libdl.so.2", l_ld =
0x37fb202da0,
  l_next = 0x7ffff7ffdb20, l_prev = 0x37fa61f678}
(gdb) p *_r_debug.r_map->l_next->l_next->l_next
$10 = {l_addr = 0, l_name = 0x7ffff7ffdb08 "/lib64/libc.so.6", l_ld =
0x37fab72b40,
  l_next = 0x37fa61e970, l_prev = 0x7ffff7ffd658}
(gdb) p *_r_debug.r_map->l_next->l_next->l_next->l_next
$11 = {l_addr = 0, l_name = 0x400200 "/lib64/ld-linux-x86-64.so.2",
l_ld = 0x37fa61ddf0, l_next = 0x0,
  l_prev = 0x7ffff7ffdb20}

-- 
Mathieu Lacage <mathieu.lacage@gmail.com>

  reply	other threads:[~2010-07-09 11:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-07 18:49 Mathieu Lacage
2010-07-08 20:32 ` Tom Tromey
2010-07-09 11:37   ` Mathieu Lacage [this message]
2010-07-09 11:42     ` Mathieu Lacage
2010-07-20 19:38     ` Tom Tromey
2010-07-25 12:25       ` Mathieu Lacage
2011-01-20 14:51         ` Mathieu Lacage
2011-01-26 10:52           ` Thiago Jung Bauermann
2011-01-28 11:10             ` Tom Tromey
2011-01-29 10:32               ` Thiago Jung Bauermann
2011-01-31 17:50                 ` Tom Tromey
2010-07-08 15:59 Mathieu Lacage

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AANLkTikX8KmJl6_gcsIEWfuJ5m3NS0LHvEZPVuS2iAJ4@mail.gmail.com \
    --to=mathieu.lacage@gmail.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).