ros-industrial/reach

Very simple custom plugin fails with segmentation fault

Closed this issue · 3 comments

I am currently trying to create a custom reach plugin. However, even the most minimal plugin fails with a segmentation fault.
The segmentation fault happens at the fist call to the plugin. In my case it is an evaluator, therefore the first call to calculateScore fails. Further debugging revealed that calls to calculateScore still work as long as the factory object still exists, i.e. in the following code,

reach/src/reach_study.cpp

Lines 321 to 325 in 0d1d854

reach::Evaluator::ConstPtr evaluator;
{
auto factory = loader.createInstance<EvaluatorFactory>(get<std::string>(eval_config, "name"));
evaluator = factory->create(eval_config);
}
calling calculateScore before line 325 works, after it, there is a segmentation fault.

Steps to reproduce and the corresponding source code can be found here: https://github.com/timonegk/reach_plugin_example

I've noticed this intermittently before as well. My understanding is that

  • the plugin loader (loader) dynamically loads a library to create factory
    • I think this library should stay loaded in memory as long as loader is in scope
  • factory uses the loaded library to produce an instance of evaluator that is independent of factory
    • In the reach and reach_ros/2 plugins, evaluator implementations are defined in separate libraries from the factories that create them; see here and here
  • When factory goes out of scope, its library should still be loaded because loader is still in scope. Similarly, the library for evaluator should still be loaded because loader is still in scope
    • In the case of the plugins in reach, they are in the same library as the rest of the core code, so that library probably can't be unloaded until the application is terminated; they may work mostly by coincidence. I don't think this is true for the reach_ros/2 plugins though

There is a chance that when factory goes out of scope, loader unloads the library that provides the implementation of factory. In your case, your factory and evaluator are defined in the same library. So if that library gets unloaded then that would explain why your evaluator segfaults.

Can you try separating your factory and evaluator into two different libraries as in the current reach and reach_ros/2 repos and see if the issue persists?

Okay; thanks for checking on that.

Further debugging revealed that calls to calculateScore still work as long as the factory object still exists

If the problem is solved by making the factories persistent, I would be okay with merging that solution