std::function and shared object libraries
Jonathan Wakely
jwakely.gcc@gmail.com
Sat Jun 13 19:48:00 GMT 2015
On 13 June 2015 at 16:00, Gabriel Marcano <gabemarcano@yahoo.com> wrote:
>
>
>> I don't see any way to avoid this, you're taking a pointer to code
>
>> defined in the shared library, then unloading the shared library, then
>> using the code that was just unloaded.
>
>
>
> That's what I figured was happening. I do find it a bit strange that the
> function needs to be called at destruction. I've been looking through the
> source code for libstdc++ trying to figure out what's happening at a lower
> level, and I'm actually a bit more confused.
>
> In particular, I'm confused by the fact that _M_manager itself is causing
> the segfault. Looking at the library code,
>
>> Manager_type _M_manager;
>> ...
>
>> typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
>> _Manager_operation);
>
> _M_manager seems to be a function pointer to a specific type of management
> code. The segfault is happening because whatever _M_manager was, it was
>
> invalidated. It seems _M_manager is set somewhere deep in the code. From
> what I can tell, _M_manager is set to something in shared.cpp, some
> internal pointer defined by _Function_base::_M_manager. There is also
> some sort of inheritance going on, but at the end of the day the core of
> the handler function seems to be the one defined by
>
> _Function_base::_M_manager. Why is accessing this function causing a
> segfault? As far as I can trace with GDB my function is NOT being called
> at destruction, so it's not the one to blame for the segfault. Unless I'm
> misunderstanding something?
Read my answer again, I already explained that.
When you do "fun = shared" you instantiate a function template.
The instantiation is in your shared library.
The address of that instantiation is assigned to fun._M_manager
When you unload the shared library that address becomes invalid.
In the destructor the manager function is called to free the resources
held by the std::function.
You can do "f = nullptr;" before unloading the library to force the
resources to be freed first, and the manager function set to null
before it becomes invalid.
More information about the Gcc-help
mailing list