This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Conservative GC and glibc data structures


Roland -

Thanks very much for the long messages, and apologies for my slow reply.

Both the information and the glibc-2.4 interface appear very useful.

The main thing that still seems unpleasant, if I understand this
correctly, is tracking down the thread descriptor for the initial
thread.  I can get the TLS part of that using the interface below, but
that seems to require a bit of work, and only works for glibc-2.4.  If I
understand correctly, even intercepting malloc and checking for dynamic
linker calls won't help.  It sounds like there is no easy way to
recognize the segment from /proc/self/maps?

It sounds like a feasible initial approach here might be to

- Make sure that all non-initial thread descriptors are scanned, which
looks easy, and probably is always a good idea.

- Test for the 2.4 interface, and add the main thread's main tls segment
at process startup.

Unfortunately, without the 2.4 interface, this doesn't guarantee much,
though it might help for some programs.  With the 2.4 interface, it
seems to cover applications that don't use dlopen, provided I'm in the
first model, and malloc is not intercepted.  In the model 2 case, I
still end up with some dynamic linker data structures getting
prematurely collected, so it doesn't really work there, by itself.

I gather it should work to combine this with your idea of checking
dynamic linker return addresses in malloc, and treating those blocks
specially.  (I think "specially" probably just means allocating them
with GC_malloc_uncollectable(), which is already there, and interacts
correctly with GC_free().)  The main down side of that seems to be an
extra load of a global and correctly predicted branch in the malloc
path, which seems neither ideal nor a showstopper.  (One could
contemplate patching non-linker call sites from malloc, but that clearly
has some other issues.)  It also adds a gcc dependency, but since all of
this is clearly already glibc dependent ...

As you say, dlopen could be handled by having each thread use
dl_iterate_phdr to enumerate its TLS segments as it is being stopped.
That perhaps needs to be somewhat optional to deal with the 1000
libraries x 1000 threads case, but it should usually be OK.

Does that sound right?

If so, it's just "a small matter of programming", while waiting for
glibc-2.4 to take over the world.

But I think an interface to track down the main thread's descriptor (or
all dynamic linker pages) would still make this significantly easier,
and reduce malloc cost by a measurable amount.  Assuming we had this,
and didn't check for calls from the dynamic linker, what per-thread
state would the collector still miss?  Anything interesting?

Hans

> -----Original Message-----
> From: Roland McGrath [mailto:roland@redhat.com] 
> Sent: Thursday, March 16, 2006 7:23 PM
> To: Boehm, Hans
> Cc: libc-alpha@sourceware.org; Filip Pizlo
> Subject: RE: Conservative GC and glibc data structures
> 
> To follow up on this: I added a couple of things to 
> glibc-2.4, which is now available and will be seen on new 
> systems like Fedora Core 5 next week.
> These give one new avenue to address the problems you 
> mentioned about TLS in particular.  (When I get a chance, I 
> will write separately about your issues relating to symbol 
> interposition.  Those issues are well-understood, but it will 
> take a while to write up the brain dump, and it doesn't boil 
> down to any simple answers.)
> 
> The additions in glibc-2.4 give you ways to see the TLS 
> blocks allocated.
> You already use dl_iterate_phdr.  I've extended the `struct 
> dl_phdr_info'
> that it gives your callback with two new fields:
> 
>     /* If there is a PT_TLS segment, its module ID as used in
>        TLS relocations, else zero.  */
>     size_t dlpi_tls_modid;
> 
>     /* The address of the calling thread's instance of this module's
>        PT_TLS segment, if it has one and it has been allocated
>        in the calling thread, otherwise a null pointer.  */
>     void *dlpi_tls_data;
> 
> The modid value is probably not of any use to you.  If you 
> wish to test it, it will be zero when there is no TLS segment 
> in that module, and nonzero (and unique among modules 
> presently loaded) when there is one.  (You will of course see 
> the PT_TLS in one of the dlpi_phdr elements too.)
> 
> The dlpi_tls_data pointer tells you the block of roots you 
> need to know, for the thread that calls dl_iterate_phdr.  It 
> will be null for a module that does have a PT_TLS when the 
> calling thread has not lazy-allocated it yet.  To find the 
> size of that block (which is of course the same for all 
> threads), you need to find the PT_TLS element in dlpi_phdr 
> and get its p_memsz value.  (I didn't make the function do 
> that for you, since it would have to do exactly the same work itself.)
> 
> The same information is also now available via dlinfo (see 
> <dlfcn.h>), using the new RTLD_DI_TLS_MODID and 
> RTLD_DI_TLS_DATA request codes.
> Here too, the data pointer is the current thread's information.
> You call dlinfo on an individual module, rather than 
> iterating through all.
> dlinfo does not take locks, which dl_iterate_phdr does.
> 
> Both of these are "soft" ABIs.  Only the new glibc-2.4 header 
> files (link.h, dlfcn.h) define the new RTLD_DI_* values and 
> the longer version of `struct dl_phdr_info'.  However, if you 
> wanted to make your sources hard-code the missing values 
> and/or struct layout, then you could build a single binary 
> that can cope with either an older libc DSO (2.3) or a newer 
> one (2.4) being loaded at run time.  For dl_iterate_phdr, the 
> second argument to the callback gives the struct size so you 
> can see if the new fields are defined.  For dlinfo, passing 
> the new request codes to an old DSO will get a -1 return with 
> dlerror reporting "unsupported dlinfo request".
> 
> I hope this helps.  These additions were simple and 
> noninvasive to make and were what was feasible for the 
> glibc-2.4 time frame.
> 
> 
> Thanks,
> Roland
> 


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