On Tue, Aug 02, 2005 at 03:44:05PM +0200, Ralf Wildenhues wrote:
> * Gleb Natapov wrote on Mon, Aug 01, 2005 at 04:58:03PM CEST:
> > On Mon, Aug 01, 2005 at 03:42:17PM +0200, Ralf Wildenhues wrote:
> > > * Gleb Natapov wrote on Sun, Jul 17, 2005 at 11:39:34AM CEST:
> > > >
> > > > I have library (lets say liba.so) that on startup checks available
> > > > hardware and loads appropriate plugin (say plugin.so) to drive the
> > > > hardware.
> > > > plugin.so uses symbols from liba.so.
> > > >
> > > > Everything works OK if liba.so linked with application, but if
> > > > application is modular by itself and use module (say module.so) that
> > > > is linked with liba.so then dlopen of plugin.so from liba.so fails with
> > > > unresolved symbols.
> > > >
> > > > How can I solve this issue?
> > >
> > > If you use Libtool/libltdl for portable modules (which you do not seem
> > > to do), look at Libtool branch-2-0 or CVS HEAD, which allows ltdlopen'ing
> > > from libraries. Make sure to read the corresponding documentation
> > > pertaining to libltdl, make use of `-module' and `-export-dynamic'.
> > >
> > The project I saw this problem with actually use libtool (not 2.0
> > though). And both flags are used.
>
> OK. Well, for portable use of modules from within a library you should
> use either branch-2-0 or HEAD.
>
> > After investigation of the problem I found that liba.so tries to load
> > plugin.so from library constructor. Even if liba.so is dlopen with
> > RTLD_GLOBAL flag set, plugin.so can't resolve symbols from liba.so
>
> Just so we don't misunderstand each other: what exactly do you mean by
> library constructor? Are you overwriting DT_INIT? (If so, you are a far
> way from portable shared libraries.)
I am talking about function marked __attribute__((constructor)).
Portability is not an issue for me.
>
> > Let me explain this one more time.
> >
> > Program 'prog' calls dlopen(liba.so, RTLD_GLOBAL), in constructor liba.so
> > calls dlopen(plugin.so) and this call fails with unresolved symbols
> > from liba.so.
> >
> > If we add function init_a() to liba.so and move dlopen(plugin.so) from
> > constructor to the function and we call this function from 'prog' after
> > dlopen (liba.so, RTLD_GLOBAL) then everything works as expected.
>
> Best would be if you showed short reproducible code. Not that I know
> whether I could help you then.
>
Attached. To compile run following:
$ gcc liba.c -shared -o liba.so
$ gcc plugin.c -shared -o plugin.so
$ gcc prog.c -ldl -o prog
Run:
$ ./prog
Load of plugin.so failed
Notice that second dlopen of plugin.so succeeds.
--
Gleb.
#include <dlfcn.h>
#include <stdio.h>
void __attribute__((constructor)) libinit()
{
if (dlopen ("./plugin.so", RTLD_NOW) == NULL)
fprintf (stderr, "Load of plugin.so failed\n");
}
int foo()
{
return 0;
}
extern int foo();
int bar ()
{
return foo();
}
#include <dlfcn.h>
#include <stdio.h>
int main ()
{
if (dlopen ("./liba.so", RTLD_NOW | RTLD_GLOBAL) == NULL)
fprintf (stderr, "liba.so load failed\n");
if (dlopen ("./plugin.so", RTLD_NOW) == NULL)
fprintf (stderr, "plugin.so load failed\n");
return 0;
}
_______________________________________________
http://lists.gnu.org/mailman/listinfo/libtool