weak_ptr, shared_ptr and dynamic libraries
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
Kyle Girard wrote:
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.
What you're doing is reasonable and would be useful if it worked, but unfortunately, I can't think of a way to fix shared_ptr to support it. The problem is that when the dynamic library creates its shared_ptr<Foo>, the supporting class template boost::detail::sp_counted_base_impl_p<Foo> is instantiated along with its vtable, so the implementation of the virtual functions ends up in libFoo.so. When you unload libFoo.so, any attempt to call one of these virtual functions leads to a crash as they are no longer present. You can probably try to create a dummy shared_ptr<Foo>( new Foo ) in main.cc in order to force the main application to also contain the shared_ptr<Foo> code. This, of course, is not a general solution if main.cc doesn't know about Foo and only deals with base classes... but it might be enough for you.
participants (2)
-
Kyle Girard
-
Peter Dimov