This is the mail archive of the
cygwin-developers
mailing list for the Cygwin project.
Re: dlclose not calling destructors of static variables.
- From: Corinna Vinschen <corinna-cygwin at cygwin dot com>
- To: cygwin-developers at cygwin dot com
- Date: Fri, 29 Jan 2010 10:32:15 +0100
- Subject: Re: dlclose not calling destructors of static variables.
- References: <4B61732F.4030804@gmail.com>
- Reply-to: cygwin-developers at cygwin dot com
Dave,
would you mind to have a look into that one? Since you have been
playing with C++ constructors/desctructors a lot lately...
Thanks,
Corinna
On Jan 28 11:21, Andrew West wrote:
> I seem to be having a problem with dlclose not calling the
> destructors of statically declared variables. I've attached a simple
> test case which I compile as follows;
>
> testlib.cpp
> g++ -g -shared testlib.cpp -o testlib
>
> testrunner.cpp
> g++ -g testrunner.cpp -o testrunner -ldl
>
> When running testrunner, I get the following output;
>
> Running test_runner
> testlib:: start
> TestClass::TestClass()
> Running test_lib
> testlib:: stop
> Segmentation fault (core dumped)
>
> Compiling and running the same code on linux gives me the expected
> result of;
>
> Running test_runner
> testlib:: start
> TestClass::TestClass()
> Running test_lib
> TestClass::~TestClass()
> testlib:: stop
>
> Digging through with gdb, __EntryPoint() registers the destructor of
> TestClass with atexit but dlclose doesn't call the atexit for the
> dll it's unloading leaving the TestClass destructor in the atexit
> list when the program exits even thou testlib.dll has been unloaded,
> hence the segfault.
>
> I'm afraid I'm don't really know much about how the internals of
> cygwin/library loading and unloading works. Is this a simply a case
> of dll_list::detach needing to call __cxa_finalize with a reference
> to the dll being unloaded?
>
> Andy
> #include <iostream>
> #include <dlfcn.h>
>
> typedef int ( *ENTRYFUNC )();
>
> int main( int argc, char** argv )
> {
> std::cout << "Running test_runner" << std::endl;
>
> void* dll = 0;
>
> dll = dlopen( "testlib.dll", RTLD_LAZY );
>
> if ( !dll )
> {
> std::cout << "Could not open library: " << dlerror() << "." << std::endl;
> return 0;
> }
>
> ENTRYFUNC dllFunc = ( ENTRYFUNC ) dlsym( dll, "__EntryPoint" );
>
> if ( !dllFunc )
> {
> std::cout << "Could not find library entry point" << std::endl;
> dlclose( dll );
> return 0;
> }
>
> dllFunc();
>
> if ( 0 != dlclose( dll ) )
> {
> std::cout << "Could not close library" << std::endl;
> return 0;
> }
>
> return 1;
> }
> #include <iostream>
> #include <cstdlib>
>
> struct TestClass {
> TestClass()
> {
> std::cout << "TestClass::TestClass()" << std::endl;
> }
> ~TestClass()
> {
> std::cout << "TestClass::~TestClass()" << std::endl;
> }
> };
>
> static void start() __attribute__ ((constructor));
> static void stop() __attribute__ ((destructor));
>
> extern "C" void __EntryPoint()
> {
> static TestClass t1;
> std::cout << "Running test_lib" << std::endl;
> }
>
> void start(void)
> {
> std::cout << "testlib:: start" << std::endl;
> }
>
> void stop(void)
> {
> std::cout << "testlib:: stop" << std::endl;
> }
>
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat