Boost logo

Boost Users :

From: Kyle Girard (kyle.girard_at_[hidden])
Date: 2006-07-10 18:00:56


Hello,
        
I was fooling around with the boost::shared_ptr and boost::weak_ptr
library and dynamic libraries and I received a segmentation fault which
I do not fully understand and I am hoping someone can shed some light on
the situation.

I am playing around with having objects in a dynamic library
which are managed by shared_ptr's return weak_ptrs to the application
My problem arises when the weak_ptrs aren't destroyed before the plugin
is unloaded.

I was hoping that the weak_ptr would become invalid when the shared_ptr
it points to is unloaded but instead it causes a segmentation fault.

I'm just starting to play around with dynamic libraries and shared_ptrs
and stuff so I don't fully understand all the caveats that go with the
territory so any information would be appreciated.

Here's a small linux example which generates the error:

main.cc == Application
foo.cc/foo.hh == Dynamic Library
make sure to set LD_LIBRARY_PATH to the appropriate directory

main.cc
=======

#include <iostream>
#include <dlfcn.h>
#include <boost/weak_ptr.hpp>
#include "Foo.hh"

using namespace std;

int main()
{
  typedef boost::weak_ptr<Foo> (*DoStuff) (void);
  void *hndl = dlopen("libFoo.so", RTLD_NOW);
  void *doStuff = dlsym(hndl, "doStuff");
// { //if I comment this in then the error goes away
    boost::weak_ptr<Foo> wpFoo = ((DoStuff)(doStuff))();
// } //if I comment this in then the error goes away
  dlclose(hndl);
  cerr << "Yay Finished" << endl;
  return 0;
}

Foo.hh
======

#ifndef FOO_HH
#define FOO_HH
#include <boost/weak_ptr.hpp>

class Foo
{
};

extern "C"
{
  boost::weak_ptr<Foo> doStuff();
}
#endif //FOO_HH

Foo.cc
======

#include "Foo.hh"
#include <vector>
#include <boost/shared_ptr.hpp>

std::vector<boost::shared_ptr<Foo> > Foos;

extern "C"
{
  boost::weak_ptr<Foo> doStuff()
  {
    Foos.push_back(boost::shared_ptr<Foo>(new Foo));
    return Foos[0];
  }
}

Makefile
========

CC = g++
LIBS = -ldl
 .cc.o:
        $(CC) -ggdb -c $<
default:
        make all
OBJS = main.o
test: main.o
        $(CC) -rdynamic -o test main.o $(LIBS)
libfoo.so: Foo.o
        g++ -shared -Wl,-soname,libFoo.so -o libFoo.so Foo.o
all: test libfoo.so
clean:
        rm -f *.so *.o test

===
end of example

thanks

Kyle


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net