kdeinit problem: LD_BIND_NOW cached by glibc

Karl Vogel karl.vogel at telenet.be
Mon Nov 22 23:52:43 CET 2004


While looking at the glibc source I noticed that it caches the
LD_BIND_NOW variable, which means that unsetting it after program start,
will not change anything for dlopen()'s done by the program.

This would also mean that the kdeinit hack in KDE will always do a
complete bind of the symbols when loading the libkdeinit_appname.so
module.

Time for a test... 

----- te.c ---
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(int argc, char *argv[])
{
        void *handle;
        int i;

        unsetenv("LD_BIND_NOW");
        for(i= 0; i<100;i++) {
        	handle= dlopen(argv[1], RTLD_LAZY);

        	if (handle == NULL)
        	        perror(dlerror());

        	dlclose(handle);
        }
        return 0;
}
-----

$ time ./te /usr/lib/libkdeinit_konsole.so

real    0m0.227s
user    0m0.171s
sys     0m0.009s
$ export LD_BIND_NOW=1
$ time ./te /usr/lib/libkdeinit_konsole.so

real    0m18.408s
user    0m17.922s
sys     0m0.413s

I also verified this with libltdl and got the same results. This clearly
shows that unsetenv("LD_BIND_NOW") has no effect on the dlopen.

This is with glibc 2.3.3 (glibc-2.3.3-74) on Fedora Core 3.


The glibc files in question:


elf/rtld.c :

static void
process_envvars (enum mode *modep)
{
 ....
        case 8:
          /* Do we bind early?  */
          if (memcmp (envline, "BIND_NOW", 8) == 0)
            {
              GLRO(dl_lazy) = envline[9] == '\0';
              break;
            }

elf/dl-open.c :

  /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
  lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GLRO(dl_lazy);


Maybe somebody can verify the test program on SuSE and/or other
distros/glibc's.


Working around this for kdeinit is possible, but will be hackish. 




More information about the Kde-optimize mailing list