Dynamic linker with global object construction problem

bridged with qdn.public.devtools
Post Reply
QNX

Dynamic linker with global object construction problem

Post by QNX » Tue Jul 23, 2002 11:57 pm

Few days ago I run into the weird problem with globally declared objects and
shared libraries.
What it comes to is that the constructor of the statically allocated object
get called twice on the same object. I had quite hard time finding out what
is going on in my real code but here is set of files producing the same
thing.
Even if I am doing something strange, something like this should not happen
(note that "testdll.so" is loaded twice, on startup and "manually" from the
"main")
We are still running QNX 6.1 (patch A) on x86 (PIII).

----------------------------------------------------------------- exe.cpp:
#include <stdio.h>
#include <dlfcn.h>

#include "dll.h"

static const char s_szObjectDllName[] = "testdll.so";

int main( int nArgC, char *ppszArgV[] )
{
printf( "Executing...\n" );

printf( "Loading shared object: %s\n", s_szObjectDllName );
dlopen( s_szObjectDllName, RTLD_NOW | RTLD_GLOBAL );

return( 0 );
}
------------------------------------------------------------------- dll.h:
class dll
{
public:
dll();
private:
dll *m_pAddress;
};
----------------------------------------------------------------- dll.cpp:
#include <stdio.h>

#include "dll.h"

dll::dll()
{
if( m_pAddress == this )
{
printf( "Already initialized @%p!\n", this );
}
else
{
printf( "Constructing DLL object @%p!\n", this );
m_pAddress = this;
}
}
----------------------------------------------------------------- dll.cpp
#include "dll.h"

static dll DllObject;

-------------------------------------------------------------------------
build commands used::

qcc -V gcc_ntox86 -shared -Wall -g -o dll.so dll.cpp
qcc -V gcc_ntox86 -shared -Wall -g -o testdll.so testdll.cpp dll.so
qcc -V gcc_ntox86 -Wall -g -o exe exe.cpp testdll.so dll.so

-------------------------------------------------------------------------
"desired" result:

Constructing DLL object @b82018f4!
Executing...
Loading shared object: testdll.so
Already initialized @b82018f4!

Jeff Baker

Re: Dynamic linker with global object construction problem

Post by Jeff Baker » Wed Jul 24, 2002 2:50 pm

This is a known bug in 6.1 that was fixed for 6.2. You're running accross
it because you're compiling your test executable with a dependency on
testdll.so AND dlopening the same object in the code. If you remove either
the dependency on the compile line OR the dlopen, this problem should go
away.
Few days ago I run into the weird problem with globally declared objects
and
shared libraries.
What it comes to is that the constructor of the statically allocated
object
get called twice on the same object. I had quite hard time finding out
what
is going on in my real code but here is set of files producing the same
thing.
Even if I am doing something strange, something like this should not
happen
(note that "testdll.so" is loaded twice, on startup and "manually" from
the
"main")
We are still running QNX 6.1 (patch A) on x86 (PIII).

----------------------------------------------------------------- exe.cpp:
#include <stdio.h
#include <dlfcn.h

#include "dll.h"

static const char s_szObjectDllName[] = "testdll.so";

int main( int nArgC, char *ppszArgV[] )
{
printf( "Executing...\n" );

printf( "Loading shared object: %s\n", s_szObjectDllName );
dlopen( s_szObjectDllName, RTLD_NOW | RTLD_GLOBAL );

return( 0 );
}
------------------------------------------------------------------- dll.h:
class dll
{
public:
dll();
private:
dll *m_pAddress;
};
----------------------------------------------------------------- dll.cpp:
#include <stdio.h

#include "dll.h"

dll::dll()
{
if( m_pAddress == this )
{
printf( "Already initialized @%p!\n", this );
}
else
{
printf( "Constructing DLL object @%p!\n", this );
m_pAddress = this;
}
}
----------------------------------------------------------------- dll.cpp
#include "dll.h"

static dll DllObject;

-------------------------------------------------------------------------
build commands used::

qcc -V gcc_ntox86 -shared -Wall -g -o dll.so dll.cpp
qcc -V gcc_ntox86 -shared -Wall -g -o testdll.so testdll.cpp dll.so
qcc -V gcc_ntox86 -Wall -g -o exe exe.cpp testdll.so dll.so

-------------------------------------------------------------------------
"desired" result:

Constructing DLL object @b82018f4!
Executing...
Loading shared object: testdll.so
Already initialized @b82018f4!

Gogi

Re: Dynamic linker with global object construction problem

Post by Gogi » Wed Jul 24, 2002 5:21 pm

Thing were not so obvious in my project and it is not so easy to get rid of
the duplicate loading (my "main" code is linking against a so and my
plug-in(s) are linking against it as well). It is easy to work around the
problem anyway as long as you know what the problem is.
Since the bug is fixed whole story is obsolete anyway.

Thanks, Gogi.


"Jeff Baker" <jbaker@qnx.com> wrote in message
news:ahmels$c2m$1@nntp.qnx.com...
This is a known bug in 6.1 that was fixed for 6.2. You're running accross
it because you're compiling your test executable with a dependency on
testdll.so AND dlopening the same object in the code. If you remove
either
the dependency on the compile line OR the dlopen, this problem should go
away.

Few days ago I run into the weird problem with globally declared objects
and
shared libraries.
What it comes to is that the constructor of the statically allocated
object
get called twice on the same object. I had quite hard time finding out
what
is going on in my real code but here is set of files producing the same
thing.
Even if I am doing something strange, something like this should not
happen
(note that "testdll.so" is loaded twice, on startup and "manually" from
the
"main")
We are still running QNX 6.1 (patch A) on x86 (PIII).

-----------------------------------------------------------------
exe.cpp:
#include <stdio.h
#include <dlfcn.h

#include "dll.h"

static const char s_szObjectDllName[] = "testdll.so";

int main( int nArgC, char *ppszArgV[] )
{
printf( "Executing...\n" );

printf( "Loading shared object: %s\n", s_szObjectDllName );
dlopen( s_szObjectDllName, RTLD_NOW | RTLD_GLOBAL );

return( 0 );
}
-------------------------------------------------------------------
dll.h:
class dll
{
public:
dll();
private:
dll *m_pAddress;
};
-----------------------------------------------------------------
dll.cpp:
#include <stdio.h

#include "dll.h"

dll::dll()
{
if( m_pAddress == this )
{
printf( "Already initialized @%p!\n", this );
}
else
{
printf( "Constructing DLL object @%p!\n", this );
m_pAddress = this;
}
}
-----------------------------------------------------------------
dll.cpp
#include "dll.h"

static dll DllObject;


-------------------------------------------------------------------------
build commands used::

qcc -V gcc_ntox86 -shared -Wall -g -o dll.so dll.cpp
qcc -V gcc_ntox86 -shared -Wall -g -o testdll.so testdll.cpp dll.so
qcc -V gcc_ntox86 -Wall -g -o exe exe.cpp testdll.so dll.so


-------------------------------------------------------------------------
"desired" result:

Constructing DLL object @b82018f4!
Executing...
Loading shared object: testdll.so
Already initialized @b82018f4!



Post Reply

Return to “qdn.public.devtools”