ros / pluginlib

Library for loading/unloading plugins in ROS packages during runtime
http://ros.org/wiki/pluginlib
BSD 3-Clause "New" or "Revised" License
57 stars 102 forks source link

pluginlib::ClassLoader destructor not unload shared library( the plugin) after going out of scope #258

Open hesham1salem opened 1 month ago

hesham1salem commented 1 month ago

Description:

I encountered an issue while using the pluginlib::ClassLoader in ROS2 humble where the shared library( the plugin) doesn't appear to be unloaded after going out of scope. This may be related to an underlying problem with poco::SharedLibrary as described in this Poco issue. which is used in class_loader repo

Steps to Reproduce:

Create a simple test program like the following:

int main(int argc, char** argv)
{
  {
    auto plugin_loader_ = std::make_shared<pluginlib::ClassLoader<tasks::task_base::SwarmBase>>("package_name",
                                                                                                "namespace::base_class");

    auto task_execution = plugin_loader_->createSharedInstance("namespace::driven_class");
  } // End of scope of ClassLoader

  while (true) {} // Loop indefinitely to check if the process still has the shared library loaded
}

Build and run the program.

Check if the shared library is loaded using the lsof command:

lsof install/package_name/lib/libbase_class.so
COMMAND    PID    USER  FD  TYPE DEVICE SIZE/OFF  NODE   NAME
node_name  PID    root  mem  REG  0,49   13865360 7394835 install/package_name/lib/libbase_class.so

The output shows that the process is still mapping to the shared library:

Kill the process and run lsof again:

lsof install/package_name/lib/libbase_class.so

At this point, no result is returned, meaning the shared library is no longer mapped by any process.

Expected Behavior: After the pluginlib::ClassLoader goes out of scope, I expected the shared library to be unloaded

Actual Behavior: The shared library remains loaded in memory, even after pluginlib::ClassLoader goes out of scope.

Possible Root Cause: This issue may be related to the underlying Poco library, specifically poco::SharedLibrary. This is similar to the issue reported in Poco Issue #3176, which ros/class_loader is based on.

System Information: ROS2 version: (humble) OS: (ubuntu 22.04) C++ Standard: (c++17) Any insight or suggestions for a workaround would be greatly appreciated.

clalancette commented 1 month ago

This issue may be related to the underlying Poco library, specifically poco::SharedLibrary. This is similar to the issue reported in Poco Issue #3176, which ros/class_loader is based on.

We haven't used the poco library in many years, so this is unrelated.

After the pluginlib::ClassLoader goes out of scope, I expected the shared library to be unloaded

Unloading libraries is tricky, especially in a multi-platform project (for instance, I believe that macOS just flat out doesn't allow libraries to be unloaded).

I don't have a great answer for you. If you happen to find some ways to fix it, we'd be happy to review a pull request.