Mystic segfault when using dlopen with static function with staticvariables inside it.

M

Markku Linnoskivi

Environment: Linux + g++ (4.3.X)

Let there be the following classes:

//libfoo <<<
struct Bar
{
Bar()
: s()
{}

Bar(const std::string& s_)
: s(s_)
{}

std::string s;
};

struct Foo
{
static Bar getBar()
{
static Bar b;
static done = false;

if (done)
{
return b;
}
std::stringstream s;
s << __FILE__ ;
}
};

//libfoo >>>>

//libX <<<
struct FooObj
{
//has instance of Foo and calls Foo:getBar()
};

extern "C"
{
FooObj* create()
{
return new FooObj;
}
}
//libX >>>

The context is a plugin system where the plugins use a common library
(libfoo) and appfoo is the host for the plugins.

There is a shared library, call it, libX that calls Foo::getBar() at
some point. And is linked during compile time to libfoo.
There is an application appfoo that opens libX via dlopen and
instantiates an FooObj from that library (using extern "C" function
create). appfoo destroys the instantiated object, closes libfoo with
dlclose and then later on opens it again with dlopen and creates a new
instance of FooObj.

At this point appfoo segfaults with a weird stack trace, mayby
pointing to std::stringstream.

What happens? This has to have something to do with the way GCC
creates/destroys the static variables or something like that.
 
M

Markku Linnoskivi

Environment: Linux + g++ (4.3.X)

Let there be the following classes:

//libfoo <<<
struct Bar
{
    Bar()
        : s()
    {}

    Bar(const std::string& s_)
        : s(s_)
    {}

    std::string s;

};

struct Foo
{
    static Bar getBar()
    {
        static Bar b;
        static done = false;

        if (done)
        {
            return b;
        }
        std::stringstream s;
        s << __FILE__ ;
   }

};

//libfoo >>>>

//libX <<<
struct FooObj
{
//has instance of Foo and calls Foo:getBar()

};

extern "C"
{
    FooObj* create()
    {
        return new FooObj;
    }}

//libX >>>

The context is a plugin system where the plugins use a common library
(libfoo) and appfoo is the host for the plugins.

There is a shared library, call it, libX that calls Foo::getBar() at
some point. And is linked during compile time to libfoo.
There is an application appfoo that opens libX via dlopen and
instantiates an FooObj from that library (using extern "C" function
create). appfoo destroys the instantiated object, closes libfoo with
dlclose and then later on opens it again with dlopen and creates a new
instance of FooObj.

At this point appfoo segfaults with a weird stack trace, mayby
pointing to std::stringstream.

What happens? This has to have something to do with the way GCC
creates/destroys the static variables or something like that.


getBar() was supposed to look like this:

static Bar getBar()
{
static Bar b;
static done = false;
if (done)
{
return b;
}
done = true;
std::stringstream s;
s << __FILE__ ;
b = Bar(s.str());
return b;
}
 
P

Peter

getBar() was supposed to look like this:

static Bar getBar()
    {
        static Bar b;
        static done = false;
        if (done)
        {
            return b;
        }
        done = true;
        std::stringstream s;
        s << __FILE__ ;
        b = Bar(s.str());
        return b;
   }


you need to use the following flags for dlopen:

RTLD_NOW | RTLD_LOCAL
| RTLD_DEEPBIND

see also

http://groups.google.com/group/comp...024eba76b4?lnk=gst&q=dlclose#b65571024eba76b4
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top