Fix a bp_shlib_disabled bug with dlopen'd libraries

Elena Zannoni ezannoni@redhat.com
Sat Aug 2 02:10:00 GMT 2003


Daniel Jacobowitz writes:
 > While investigating what is probably a different dlopen issue, I stumbled on
 > this.  Build a trivial shared library, and load it.  Set a breakpoint in it,
 > and re-run.  We get hopelessly confused.
 > 

I am also looking at some shlib stuff, these days.  Related to this, I
see another weirdness happening: set a breakpoint in a shared library
(like 'break printf'), before you say run, and the shlibs are not
loaded already. Then say 'set debug target 1' and 'run'.  Watch for
the addresses at which gdb inserts breakpoints.  It inserts a
breakpoint at the dynamic linker, and one in printf. The former gets
relocated properly, in enable_break(), but the printf breakpoint is
not relocated at all. In spite of this, as in your case, for some pure
lucky coincidence, the insert operation for the printf breakpoint
succeeds.

Then the program is run, and it stops, as first thing, at the dynamyc
linker.  At that point, the solibs will be loaded, and the printf
breakpoint relocated properly. Indeed, the breakpoint in printf is
hit, and the address shown at that point is different from the one we
saw when we first set it.

This is biting me in case of PIE binaries, because the original/non
relocated address of, say, 'main' is not in any memory that gdb can
access.

So, I am wondering if a more drastic fix is needed here. And this may
fix your case as well. I haven't thought this completely through yet,
but I wanted to let you know, just in case you are running into this
as well.

elena


 > The problem occurs in remove_breakpoints (), which returns on the first
 > failure - so breakpoints_inserted gets out of sync with reality.  Rather
 > than fix it there, I went back to find the root cause of the problem in
 > remove_breakpoint.  Turns out we were "inserting" a breakpoint before the
 > shared library it belonged to was loaded.  Somehow, this led to us failing
 > to remove it, and then when we tried to single-step past it thinking it had
 > been removed, the inferior segfaulted.
 > 
 > Easiest fix was this.  Don't just try to access target memory - the page
 > might have been mapped for some other reason, which it appears to be on my
 > system.  In fact, this library gets loaded where /etc/ld.so.cache is mmaped
 > during the initial library search!  No wonder bad things happened.
 > 
 > A possibly better fix is to check by name that the right shared library is
 > loaded; should I do that?  A definitely better fix would be to make
 > breakpoint_re_set_one communicate with this mechanism, instead of just
 > spewing errors to the terminal about undefined functions; that way we'd
 > actually know when to reset the breakpoint.  But that's quite tricky to do.
 > 
 > Comments?  Michael, I'd like to fix this for 6.0...
 > 
 > -- 
 > Daniel Jacobowitz
 > MontaVista Software                         Debian GNU/Linux Developer
 > 
 > 2003-07-30  Daniel Jacobowitz  <drow@mvista.com>
 > 
 > 	* breakpoint.c (re_enable_breakpoints_in_shlibs): Only re-enable
 > 	a bp_shlib_disabled breakpoint if there is a shared library mapped
 > 	at its expected address.
 > 
 > Index: breakpoint.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/breakpoint.c,v
 > retrieving revision 1.125
 > diff -u -p -r1.125 breakpoint.c
 > --- breakpoint.c	2 Jul 2003 16:24:00 -0000	1.125
 > +++ breakpoint.c	31 Jul 2003 01:22:29 -0000
 > @@ -4122,10 +4122,12 @@ re_enable_breakpoints_in_shlibs (void)
 >      if (b->enable_state == bp_shlib_disabled)
 >      {
 >        char buf[1];
 > +      char *lib;
 >  
 >        /* Do not reenable the breakpoint if the shared library
 >           is still not mapped in.  */
 > -      if (target_read_memory (b->address, buf, 1) == 0)
 > +      lib = PC_SOLIB (b->address);
 > +      if (lib && target_read_memory (b->address, buf, 1) == 0)
 >  	b->enable_state = bp_enabled;
 >      }
 >  }



More information about the Gdb-patches mailing list