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;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple