Rant: roscore + rviz + 64bit – strange error in librviz_default_plugin.so

Today I encountered a strangest error of them all. A missing library that exists.
A library that noone calls. Noone requires. Noone depends on it. Noone mentions in their src.
Yet when you remove it, the program breaks. How, on the deepest ponds of hell I ask, how?!

Cherry on the top: it is missing even when it exists. That’s kinda new.

It all began with a quest to gently push ROS into the world of lib64. That is, install ROS Lunar desktop on a pure 64bit Slackware. No multilib, no tinkering with “ln -s lib64 lib”, and so on. No tricks. Just patch the whole damn src directory and be done with it.

To be fair, after 3 days I am almost done. roscore works, communicates, does everything roscore should. Yet, when I call rviz, I get:

rviz2

rviz3
(Google-friendly error:)

[ERROR] [1497042832.772480194]: PluginlibFactory: The plugin for class 'rviz/Orbit' failed to load.  Error: Could not find library corresponding to plugin rviz/Orbit. Make sure the plugin description XML file has the correct name of the library and that the library actually exists.

And after that if I hit alt-tab I get Segmentation Fault.

Just for a moment I linked “ln -s lib64 lib” for compability and got:

rviz1

Ok, so the compile was OK, just a misplaced library, but which one? lsof to the rescue:

lsof | grep rviz | grep "install_isolated/lib/"

and the result (part of):

rviz      17296             anil  mem       REG                8,1  7328320  62656812 /home/anil/ros_lunar/install_isolated/lib/librviz_default_plugin.so
QXcbEvent 17296 17297       anil  mem       REG                8,1  7328320  62656812 /home/anil/ros_lunar/install_isolated/lib/librviz_default_plugin.so
QDBusConn 17296 17308       anil  mem       REG                8,1  7328320  62656812 /home/anil/ros_lunar/install_isolated/lib/librviz_default_plugin.so

Ok, time to find out who exactly is calling this library:

ldd bin/* | grep librviz_default_plugin.so
ldd lib64/* | grep librviz_default_plugin.so

Nobody? Seriously?
Ok, time to grab the big guns, just in case I am missing anything

find ./ -type f -executable | xargs ldd > lista4.txt

NOTHING? Ok, it’s a source related thing.

2 hours later, no clue. I honestly don’t know why does this library end up being called from lib/ when it is quite correctly placed in lib64/ during the compile process.
Just to be sure, I checked if this is the only one causing trouble:

rm lib
mkdir lib
cp lib64/librviz_default_plugin.so lib/

Yeap, that’s the one.

I checked rviz, but after last patch it behaves nicely, the only mention of librviz_default_plugin can be traced to rviz/default_plugin/CMakeLists.txt with rviz_DEFAULT_PLUGIN_LIBRARY_TARGET_NAME variable, rviz-extras.cmake.in and a pair of rviz-extras.cmake + default_plugin_location.cmake (after compile) but they DON’T contain any visible information about explicit placement in the lib directory.

The tale is to be continued after a break and a cup of coffee.

(one dreadful morning later)

Ok, so it seems the Poco::SharedLibrary is getting a wrong path to the library itself, the name is being grabbed from plugin_description.xml: . I’m used debugging code in the class_loader to see what is being passed on to Poco and the result is:

class_loader.class_loader_private: Attempting to load library /home/anil/ros_lunar/install_isolated/lib/lib64/librviz_default_plugin.so on behalf of ClassLoader handle 0x1550d70...
class_loader.class_loader_private: Attempting to load library /home/anil/ros_lunar/install_isolated/lib/lib64/librviz_default_plugin.so on behalf of ClassLoader handle 0x1589af0...
class_loader.class_loader_private: Attempting to load library /home/anil/ros_lunar/install_isolated/lib/lib64/librviz_default_plugin.so on behalf of ClassLoader handle 0x15b0890...

Even if I modify the line, the lib part stays. I wonder, which instance is adding it here? The hunt goes on…

(two hours later)

Found it. Not class_loader’s fault, but again – catkin. When called upon:

catkin_find --lib

the only paths returned ended with lib. So I modified find_in_workspaces.py a bit:

def find_in_workspaces(search_dirs=None, project=None, path=None, _workspaces=None, considered_paths=None, first_matching_workspace_only=False, first_match_only=False, workspace_to_source_spaces=None, source_path_to_packages=None):
    search_dirs = _get_valid_search_dirs(search_dirs, project)
    if 'libexec' in search_dirs:
        search_dirs.insert(search_dirs.index('libexec'), 'lib64')
    if 'lib' in search_dirs:
        search_dirs.insert(search_dirs.index('lib'), 'lib64')
...

and now catkin_find returns a correct collection of lib64 directories. At last.