Package: libc6-dev Version: 2.3.2 Hi.
I've encountered a problem with libdl.so. The dlsym(RTLD_NEXT, "foo") is broken with runtime linked libraries. Here are 2 little programs and 4 libraries to underline the faulty behavi= our: # the libraries: for i in 1 2 3 4 do cat > lib$i.c <<EOF #include <stdio.h> #include <dlfcn.h> void foo() { void (*next_foo)(void); printf("lib$i.foo()\n"); if (next_foo =3D (void (*)(void)) dlsym(RTLD_NEXT, "foo")) next_foo(= ); } EOF gcc -shared -fPIC lib$i.c -o lib$i.so -D_GNU_SOURCE done # the test program liking libs at compile time: cat > chain.c <<EOF #include <dlfcn.h> extern void foo(); int main() { foo(); return 0; } EOF gcc chain.c -o chain -L. -l1 -l2 -l3 -l4 -ldl LD_LIBRARY_PATH=3D.:$LD_LIBRARY_PATH ./chain #And the result : # # lib1.foo() # lib2.foo() # lib3.foo() # lib4.foo() # # And now a runtime linking version: # cat > chain2.c <<EOF #include <dlfcn.h> int main() { void *l1, *l2, *l3, *l4; void (*bar)(); l1 =3D dlopen("lib1.so", RTLD_NOW | RTLD_GLOBAL); l2 =3D dlopen("lib2.so", RTLD_NOW | RTLD_GLOBAL); l3 =3D dlopen("lib3.so", RTLD_NOW | RTLD_GLOBAL); l4 =3D dlopen("lib4.so", RTLD_NOW | RTLD_GLOBAL); bar =3D (void (*)()) dlsym(RTLD_DEFAULT, "foo"); bar(); dlclose(l4); dlclose(l3); dlclose(l2); dlclose(l1); return 0; } EOF gcc chain2.c -o chain2 -ldl -D_GNU_SOURCE # LD_LIBRARY_PATH=3D.:$LD_LIBRARY_PATH ./chain2 # # And the result : # # lib1.foo() # On alternate plateforms (bsd/libtld, Sun/libdl) the result is : lib1.foo() lib2.foo() lib3.foo() lib4.foo() Here is a more verbose version of chain2: cat > chain5.c <<EOF #include <dlfcn.h> int main() { void *l1, *l2, *l3, *l4; void (*bar)(); l1 =3D dlopen("lib1.so", RTLD_NOW | RTLD_GLOBAL); bar =3D (void (*)()) dlsym(l1, "foo"); printf("l1 is %x l1.foo is %x\n", l1, bar); l2 =3D dlopen("lib2.so", RTLD_NOW | RTLD_GLOBAL); bar =3D (void (*)()) dlsym(l2, "foo"); printf("l2 is %x l2.foo is %x\n", l2, bar); l3 =3D dlopen("lib3.so", RTLD_NOW | RTLD_GLOBAL); bar =3D (void (*)()) dlsym(l3, "foo"); printf("l3 is %x l3.foo is %x\n", l3, bar); l4 =3D dlopen("lib4.so", RTLD_NOW | RTLD_GLOBAL); bar =3D (void (*)()) dlsym(l4, "foo"); printf("l4 is %x l4.foo is %x\n", l4, bar); bar =3D (void (*)()) dlsym(l1, "foo"); printf("l1.foo is %x \n", bar); bar =3D (void (*)()) dlsym(l2, "foo"); printf("l2.foo is %x \n", bar); bar =3D (void (*)()) dlsym(l3, "foo"); printf("l3.foo is %x \n", bar); bar =3D (void (*)()) dlsym(l4, "foo"); printf("l4.foo is %x \n", bar); bar =3D (void (*)()) dlsym(RTLD_DEFAULT, "foo"); printf("default foo is %x \n", bar); bar(); dlclose(l4); dlclose(l3); dlclose(l2); dlclose(l1); return 0; } EOF gcc chain5.c -o chain5 -ldl -D_GNU_SOURCE LD_LIBRARY_PATH=3D.:$LD_LIBRARY_PATH ./chain5 And the result looks like this : l1 is 804a018 l1.foo is 5556d584 l2 is 804a3b0 l2.foo is 55570584 l3 is 804a710 l3.foo is 55572584 l4 is 804aa70 l4.foo is 55574584 l1.foo is 5556d584 l2.foo is 55570584 l3.foo is 55572584 l4.foo is 55574584 default foo is 5556d584 lib1.foo() Running the chain2 program with LD_DEBUG=3D"files symbols" gives : 14129: symbol=3Ddlsym; lookup in file=3D./chain2 14129: symbol=3Ddlsym; lookup in file=3D/lib/tls/libdl.so.2 14129: symbol=3D_dl_sym; lookup in file=3D./chain2 14129: symbol=3D_dl_sym; lookup in file=3D/lib/tls/libdl.so.2 14129: symbol=3D_dl_sym; lookup in file=3D/lib/tls/libc.so.6 14129: symbol=3Dfoo; lookup in file=3D./chain2 14129: symbol=3Dfoo; lookup in file=3D/lib/tls/libdl.so.2 14129: symbol=3Dfoo; lookup in file=3D/lib/tls/libc.so.6 14129: symbol=3Dfoo; lookup in file=3D/lib/ld-linux.so.2 14129: symbol=3Dfoo; lookup in file=3Dlib1.so --> foo is found in lib1.so lib1.foo() 14129: symbol=3Dfoo; lookup in file=3D/lib/tls/libc.so.6 14129: symbol=3Dfoo; lookup in file=3D/lib/ld-linux.so.2 --> Then all other lib$i.so are ignored : 14129: symbol=3Ddlclose; lookup in file=3D./chain2 14129: symbol=3Ddlclose; lookup in file=3D/lib/tls/libdl.so.2 14129: symbol=3D_dl_close; lookup in file=3D./chain2 14129: symbol=3D_dl_close; lookup in file=3D/lib/tls/libdl.so.= 2 14129: symbol=3D_dl_close; lookup in file=3D/lib/tls/libc.so.6 14129: Apparently, the problem is not new and may not be specific to debian. Regards, Yann LANGLAIS http://ilay.org [EMAIL PROTECTED] -- I r i s L i l a é A n g e l a o Y a n n . o r g