Re: Concurrent usage of glibc 2.2.4 and 2.3.2
From: Myself (pardillaco_at_yahoo.com)
Date: 04/11/04
- Next message: Dances With Crows: "Re: RedHat ethernet setup"
- Previous message: Fadzi Ushewokunze: "RedHat ethernet setup"
- In reply to: John Reiser: "Re: Concurrent usage of glibc 2.2.4 and 2.3.2"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 10 Apr 2004 18:14:06 -0700
Hi,
First at all, thanks John for your help. I haven't still
managed to make my app work, but I managed to simplify the
problem, and (hopefully) make it repeatable.
John Reiser <jreiser@BitWagon.com> wrote in message news:<c4s42s0c8p@enews2.newsguy.com>...
> ...
> You must invoke the corresponding version of ld-linux.so.2 whenever
> you use a different libc.so.6:
> /lib/ld-2.2.4.so --library-path <path> my_app <args>
> where libc-2.2.4.so is found in <path>, etc. The typical way to do this
> is to add another level of indirection by making my_app a script:
> #!/bin/sh
> # perhaps could use /usr/lib/env as light-weight shell
> exec /lib/ld-2.2.4.so --library_path <path> my_lib/my_app "$@"
> where <path> overrides LD_LIBRARY_PATH and any other attempt to set
> a path for ld.so. If the parent checks not only for executable my_app
> but also for ELF, then you must make an ELF version of such a script.
>
I'm still with the same problem. First, I realized that adding a
--library-path option to the RTL does not affect the LD_LIBRARY_PATH
environment variable.
I wrote the following program (fork.c). The parent process forks a
child process, which execve's /bin/ls (that's how Communicator 4.8
fires the dns helper process). Before the fork, the parent process
prints the LD_LIBRARY_PATH variable it will call the child, which
will be the same /bin/ls is execve'd with.
fork.c
------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
extern char **environ;
int main()
{
int i;
int fkid;
for (i = 0; environ[i] != NULL; i++)
if (strncmp (environ[i], "LD_LIBRARY_PATH", 15) == 0)
printf ("[%i] environ[%i] = %s\n", getpid(), i, environ[i]);
printf ("[%i] fork()\n", getpid());
fkid = fork();
if (fkid < 0) {
fprintf(stderr, "error: fork returned -1 (%s)", strerror(errno));
exit(1);
} else if (fkid == 0) {
// the child
char* nargv[4];
nargv[0] = (char *) malloc (10 * sizeof(char));
strcpy (nargv[0], "ls");
nargv[1] = (char *) malloc (10 * sizeof(char));
strcpy (nargv[1], "-Flags");
nargv[2] = (char *) malloc (10 * sizeof(char));
strcpy (nargv[2], "/tmp/k");
nargv[3] = NULL;
printf ("[%i] execve(\"/bin/ls\", [\"%s\", \"%s\", \"%s\"],
environ)\n",
getpid(), nargv[0], nargv[1], nargv[2]);
execve ("/bin/ls", nargv, environ);
} else {
/* the parent just waits 1 second */
usleep(1000000);
}
return 0;
}
---------------------------------------------------------------------------
Now I try to play with it.
> gcc.2.96 -g -Wall -O0 fork.c -o fork
> ldd -v fork
libc.so.6 => /lib/i686/libc.so.6 (0x40017000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Version information:
./fork:
libc.so.6 (GLIBC_2.1.3) => /lib/i686/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/i686/libc.so.6
/lib/i686/libc.so.6:
ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_2.0) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
> ./fork
[10684] environ[30] =
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib:/usr/local/lib:/usr/sww/lib:/usr/kerberos/lib:/usr/local/intel/bin/lib:/usr/lib/kde2
[10684] fork()
[10685] execve("/bin/ls", ["ls", "-Flags", "/tmp/k"], environ)
total 24
4 drwxrwxr-x 2 myself mygroup 4096 Apr 10 14:17 ./
16 drwxrwxrwt 24 root mygroup 16384 Apr 10 17:50 ../
4 -rw-rw-r-- 1 myself mygroup 2 Apr 10 14:17
this_is____tmp_k
Here the LD_LIBRARY_PATH points to the main glibc libraries (2.3.2),
so /bin/ls works perfectly.
> env /lib/2.2.4/ld-linux.so.2 --library-path /lib/2.2.4 ./fork
[10700] environ[30] =
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib:/usr/local/lib:/usr/sww/lib:/usr/kerberos/lib:/usr/local/intel/bin/lib:/usr/lib/kde2
[10700] fork()
[10701] execve("/bin/ls", ["ls", "-Flags", "/tmp/k"], environ)
total 24
4 drwxrwxr-x 2 myself mygroup 4096 Apr 10 14:17 ./
16 drwxrwxrwt 24 root mygroup 16384 Apr 10 17:52 ../
4 -rw-rw-r-- 1 myself mygroup 2 Apr 10 14:17
this_is____tmp_k
Now I'm expliciting that I want the 2.2.4 RTL to be used, and that I
want
the library path to be the one where glibc 2.2.4 resides. It still
works.
I'd say the reason is that the LD_LIBRARY_PATH is still unaffected, so
while the parent process is run with the 2.2.4 libraries, the child is
run with the 2.3.2 ones.
> env LD_LIBRARY_PATH=/lib/2.2.4 /lib/2.2.4/ld-linux.so.2 --library-path /lib/2.2.4 ./fork
[10702] environ[30] = LD_LIBRARY_PATH=/lib/2.2.4
[10702] fork()
[10703] execve("/bin/ls", ["ls", "-Flags", "/tmp/k"], environ)
ls: /lib/ld-linux.so.2: version `GLIBC_2.1.1' not found (required by
/lib/2.2.4/libc.so.6)
ls: /lib/ld-linux.so.2: version `GLIBC_2.2.3' not found (required by
/lib/2.2.4/libc.so.6)
ls: /lib/ld-linux.so.2: version `GLIBC_2.2' not found (required by
/lib/2.2.4/libc.so.6)
Now I'm setting LD_LIBRARY_PATH before expliciting the 2.2.4 RTL. The
parent process works perfectly, and states that its LD_LIBRARY_PATH
points to the 2.2.4 libraries. The child inherits the parent's
environment, so it gets libc.so.6 from the 2.2.4 directory. Alas,
libc.so.6 manages to go back to /lib/ld-linux.so.2, which corresponds
to 2.3.2. We're back to the version hell.
How could I force forked child processes to use the same RTL than
their parent?
Regards.
-pardillaco
- Next message: Dances With Crows: "Re: RedHat ethernet setup"
- Previous message: Fadzi Ushewokunze: "RedHat ethernet setup"
- In reply to: John Reiser: "Re: Concurrent usage of glibc 2.2.4 and 2.3.2"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|