[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dlsym() and C++



Quoting Pierre Phaneuf (pp@ludusdesign.com):

> The symbol you were asking for was mangled in the lib, which made it
> look like "ugga__Fv", but you were asking for "ugga", which didn't
> exist. You get a NULL pointer instead, which you go right away and call,
> causing a segfault.

Yes, I understand that.

> All you need to know is that 'who has the class definition does the
> "new"'. If the class definition is in the header file, when the
> application will "new" the class, it could be different in size than
> what the shared library expect, and the vtable in the shared library
> could be different from what the application expect.
> 
> One trick that I use is this. In the header file:
> 
> class Foo {
>  public:
>  /* everything short of the constructor must be pure virtual */
>  /* This is stable public interfaces that should change very rarely */
>   virtual void doStuff() = 0;
> };

This is exactly what ClanLib does. It's great that we agree on that one.


When I realized that the coredumper prog didn't show shit, I decided to
rewrite the dynamic linking part of ClanLib, and there's still something
rotten! Note that I'm trying to link C functions from zlib, and thus does
not have the name mangling problems:

typedef void* gzFile;

gzFile (*gzdopen)(int, const char*);
int (*gzclose)(gzFile);
int (*gzread)(gzFile, void *, unsigned int);

void main()
{
	cout << "gzdopen pointer: " << gzdopen << endl;
	gzdopen = NULL; // <-- ClanLib CRASHES HERE!!!

	// do some dlopen(), dlsym() here...

	// init of clanlib and call the CL_ClanApplication global
	// instance (just like mfc eg. does).
}

ClanLib is a C++ library, and the application that links ClanLib uses the
-l option to do it. (the above code is placed in the library).

As far as I can tell, the dynamic linker somehow doesn't link all references
to the gzdopen function pointer correctly. I tried to debug it with gdb. If
I ask what address the gzdopen is located at (info address gzdopen), I get a
different pointer than the above cout tells.

I havn't been able to reproduce the problem outside ClanLib, so I'm a bit
clueless on what's going on here. :-(

-- 
Magnus Norddahl
ClanSoft