Coder Social home page Coder Social logo

ros / class_loader Goto Github PK

View Code? Open in Web Editor NEW
33.0 33.0 91.0 729 KB

ROS-independent library for dynamic class (i.e. plugin) introspection and loading from runtime libraries

Home Page: http://www.ros.org/wiki/class_loader

CMake 8.31% C++ 81.31% Python 2.05% C 8.33%

class_loader's Introduction

Robot Operating System (ROS)
===============================================================================

ROS is a meta-operating system for your robot.  It provides
language-independent and network-transparent communication for a
distributed robot control system.

Installation Notes
------------------

For full installation instructions, including system prerequisites and
platform-specific help, see:

  http://wiki.ros.org/ROS/Installation

class_loader's People

Contributors

cottsay avatar davetcoleman avatar dawagner avatar de-vri-es avatar dirk-thomas avatar dlu avatar eacousineau avatar esteve avatar garyservin avatar gbiggs avatar goldhoorn avatar jmachowinski avatar johnsonshih avatar kejxu avatar mgrrx avatar mikaelarguedas avatar mikepurvis avatar mirzashah avatar nuclearsandwich avatar rhaschke avatar saarnold avatar sksavant avatar v4hn avatar vrabaud avatar wjwwood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

class_loader's Issues

Use of C++11

Background Information

The packages rosbag and rosbag_store includes headers from this package when the minimal installation from source is attempted. ROS assumes C++98, not C++11 and so the CMakeLists.txt don't have

set(CMAKE_CXX_STANDARD 11) # or 14 or 17, but 11 suffices for compilation

Issue

This package uses several new features of C++11 (and newer) including std::shared_ptr<T>, std::unique_ptr<T>, nullptr despite boost being the default standard in ROS.

This causes compilation error (which is easily fixed).

Solution

Either

  • The CMakeLists.txt file of dependencies need to be changes and sacrifice portability for compilers not supporting C++11 or later

OR

  • Changes need to be made in this repository to accommodate the compatibility issue.

After the discussion, I'd be happy to send PR to whatever solution is deemed as the correct one.

compiler warning from class_loader header

When compiling with clang I get:

/Users/william/ros_catkin_ws/install_isolated/include/class_loader/class_loader.h:195:109: warning: control reaches end of non-void function [-Wreturn-type]
    static bool hasUnmanagedInstanceBeenCreated(bool has_it){has_unmananged_instance_been_created_ = has_it;}
                                                                                                            ^
1 warning generated.

Pretty minor, but valid warning.

[ros2] Cannot find Poco on Windows

I was testing a build of the master of ROS 2 on Windows 10 with VS2017 (following the build instruction carefully), but I cannot compile the class_loader package. The error is in the cmake phase, and regards the POCO library. I succesfully built the poco_vendor package.

The command for building:

colcon build --merge-install --packages-select class_loader --event-handlers console_direct+

and the error:

Starting >>> class_loader
[ . . . ]
-- Using PYTHON_EXECUTABLE: C:/Python37/python.exe
-- Found console_bridge_vendor: 1.2.0 (C:/ROS2/install/share/console_bridge_vendor/cmake)
-- Found poco_vendor:  (C:/ROS2/install/share/poco_vendor/cmake)
CMake Error at CMakeLists.txt:22 (find_package):
  By not providing "FindPoco.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Poco", but
  CMake did not find one.

  Could not find a package configuration file provided by "Poco" with any of
  the following names:

    PocoConfig.cmake
    poco-config.cmake

  Add the installation prefix of "Poco" to CMAKE_PREFIX_PATH or set
  "Poco_DIR" to a directory containing one of the above files.  If "Poco"
  provides a separate development package or SDK, be sure it has been
  installed.

[ . . . ]
---
Failed   <<< class_loader       [ Exited with code 1 ]

Summary: 0 packages finished [11.3s]
  1 package failed: class_loader
  1 package had stderr output: class_loader

AFAIK, the poco_vendor will install a version of the POCO library (and in fact it is). But still I cannot find the required cmake files. Am I missing something?

Edit: the ros2/ros2.repos in the master branch points to the ros/class_loader repository in the ros2 branch, that is the version I cannot compile.

Project 'class_loader' specifies '/include' as an include dir

CMake Error at /home/janr/.cache/yay/ros-melodic-class-loader/src/build/devel/share/class_loader/cmake/class_loaderConfig.cmake:113 (message):
  Project 'class_loader' specifies '/include' as an include dir, which is not
  found.  It does neither exist as an absolute directory nor in
  '/home/janr/.cache/yay/ros-melodic-class-loader/src/class_loader-0.4.1//include'.
  Check the issue tracker 'https://github.com/ros/class_loader/issues' and
  consider creating a ticket if the problem has not been reported yet.
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/catkinConfig.cmake:76 (find_package)
  test/CMakeLists.txt:4 (find_package)

Progress toward Quality Level 1

This issue tracks the progression of class_loader to Quality Level 1 and a 1.0 version level. It follows the outline described in REP 2004.
This issue tracks the progression of rmw_implementation to Quality Level 1 and a 1.0 version level. It follows the outline described in REP 2004.

1 Version Policy:

  • 1.i Must have a version policy (e.g. semver)
  • 1.ii Must be at a stable version (e.g. for semver that means version >= 1.0.0)
  • 1.iii Must have a strictly declared public API - N/A
  • 1.iv Must have a policy for API stability
  • 1.v Must have a policy for ABI stability
  • 1.vi Must have a policy that keeps API and ABI stability within a released ROS distribution

2 Change Control Process:

  • 2.i Must have all code changes occur through a change request (e.g. pull request, merge request, etc.)
  • 2.ii Must have confirmation of contributor origin (e.g. DCO, CLA, etc.)
  • 2.iii Must have peer review policy for all change requests (e.g. require one or more reviewers)
  • 2.iv Must have Continuous Integration (CI) policy for all change requests
  • 2.v Must have documentation policy for all change requests

3 Documentation:

  • 3.i Must have documentation for each "feature" (e.g. for rclcpp: create a node, publish a message, spin, etc.) N/A
  • 3.ii Must have documentation for each item in the public API (e.g. functions, classes, etc.) N/A
  • 3.iii Must have a declared license or set of licenses
  • 3.iv Must state copyrights within the project and attribute all authors
  • 3.v Must have a "quality declaration" document, which declares the quality level and justifies how the package meets each of the requirements
    • 3.v.a Must have a section in the repository's README which contains the "quality declaration" or links to it
    • [v] 3.v.b Should register with a centralized list of 'Level N' packages, if one exists, to allow for peer review of the claim (counting REP-2005 as such list)
    • 3.v.c Must reference any 'Level N' lists the package belongs to, and/or any other peer review processes undergone

4 Testing:

  • 4.i Must have system tests which cover all items in the "feature" documentation

  • 4.ii Must have system, integration, and/or unit tests which cover all of the public API

  • 4.iii Code Coverage:

    • 4.iii.a Must have code coverage tracking for the package
    • 4.iii.b Must have and enforce a code coverage policy for new changes
    • not required but stating something like "above 95%" as a minimum would be good too (to match developer guide)
  • 4.iv Performance:

    • 4.iv.a Must have performance tests (exceptions allowed if they don't make sense to have) N/A
    • 4.iv.b Must have a performance regression policy (i.e. blocking either changes or releases on unexpected performance regressions)
  • 4.v Linters and Static Analysis:

    • 4.v.a Must have a code style and enforce it
    • 4.v.b Must use static analysis tools where applicable

5 Dependencies:

  • Must not have direct runtime "ROS" dependencies which are not at the same level as the package in question ('Level N'), but...
  • May have optional direct runtime "ROS" dependencies which are not 'Level N', e.g. tracing or debugging features that can be disabled
  • Must have justification for why each direct runtime "non-ROS" dependency is equivalent to a 'Level N' package in terms of quality

6 Platform Support:

  • Must support all target platforms for the package's ecosystem.
    For ROS 2 this means supporting all tier 1 platforms, as defined in REP-2000

7 Security

  • Must have a declared Vulnerability Disclosure Policy and adhere to a response schedule for addressing security vulnerabilities

Remove raw pointer interface

There have been a few issues already referencing the known memory leak in this code with the metaobjects.
#131
ros/pluginlib#126

In #186 to potentially resolve these memory leaks, @hidmic mentioned a goal to remove the raw pointer interface from the existing code. #186 (review). As humble will soon be released, I wanted to create this ticket to formally track this effort.

Was there a reason or limitation for not using smart pointers (e.g. a smart pointer for AbstractMetaObjectBase in the FactoryMap / graveyard MetaObjectVector)?

Could not find a package configuration file provided by "ament_cmake" with any of the following names:

Latest relase of this package, ros-melodic installation.

CMake Warning at CMakeLists.txt:16 (find_package):
  By not providing "Findament_cmake.cmake" in CMAKE_MODULE_PATH this project
  has asked CMake to find a package configuration file provided by
  "ament_cmake", but CMake did not find one.

  Could not find a package configuration file provided by "ament_cmake" with
  any of the following names:

    ament_cmakeConfig.cmake
    ament_cmake-config.cmake

  Add the installation prefix of "ament_cmake" to CMAKE_PREFIX_PATH or set
  "ament_cmake_DIR" to a directory containing one of the above files.  If
  "ament_cmake" provides a separate development package or SDK, be sure it
  has been installed.


CMake Error at CMakeLists.txt:19 (find_package):
  By not providing "Findconsole_bridge_vendor.cmake" in CMAKE_MODULE_PATH
  this project has asked CMake to find a package configuration file provided
  by "console_bridge_vendor", but CMake did not find one.

  Could not find a package configuration file provided by
  "console_bridge_vendor" with any of the following names:

    console_bridge_vendorConfig.cmake
    console_bridge_vendor-config.cmake

  Add the installation prefix of "console_bridge_vendor" to CMAKE_PREFIX_PATH
  or set "console_bridge_vendor_DIR" to a directory containing one of the
  above files.  If "console_bridge_vendor" provides a separate development
  package or SDK, be sure it has been installed.

Same issue with other package: ros/ros_environment#15

Library/Dependency Detetction; Bug?

Have possibly identified a bug in dependency detection. I am not sure if this should be filed against this library, catkin, and/or conda.

Environment:
Docker image w/ Ubuntu 18.04
Miniconda 4.8.2 (python 3.7)
ROS Melodic

environment.yml

name: venv
channels:
  - conda-forge
dependencies:
  - python=3.6
  - pip
  - numpy
  - ros-core
  - ros-actionlib
  - ros-dynamic-reconfigure
  - rosinstall_generator
  - rosinstall
  - catkin_tools
  - pytorch
  - numexpr

Using conda env create -f environment.yml to setup the environment, the generated cmake files identify libconsole_bridge.so.0.4 as being required. As best as I can tell that stems from the dependency identified in class_loader's package.xml file, specifically line 23. On Ubuntu 18.04 this package does indeed currently point to a 0.4 version of the libconsole_bridge library however the development (and runtime) packages are not installed on this system. This was verified by attempting to install with apt-get install libconsole-bridge-dev libconsole-bridge0.4 and seeing it confirm if these should be installed. From the conda env create it is installing the latest release of console_bridge, in this case 1.0.0. We are able to work around this issue by including console_bridge=0.4.4 which forces the env to have a version that matches that of the package that would be provided by the host system. Previously we did not explicitly include console_bridge in the environment.yml file but allowed the dependencies of other components to pull this in. Explicitly including it like this seems very likely to break when the host repositories are updated.

The library was tracked back to class_loader by reviewing an strace of conda env create as it wasn't clear where this dependency was coming from. Using ldd, it confirmed that libclass_loader.so was linked against console_bridge 0.4. Again using apt-get install I can confirm that class_loader was not installed via the system package manager.

Is there something we should be doing when installing in this manner to ensure the correct versions are included? Is there the equivalent of pip freeze that can generate a full environment file with versions for every component to lock things in place until we choose to do an upgrade or change a component?

linking tests fails with CMAKE_BUILD_TYPE=Debug

Without specifying the build type Poco_LIBRARIES contains /usr/lib/libPocoFoundation.so;dl. When building debug the variable only contains dl - I assume because no debug libraries are available on the system.

As a result building the tests fails with unresolved symbols:

../devel/lib/libclass_loader.so: undefined reference to `typeinfo for Poco::RuntimeException'
../devel/lib/libclass_loader.so: undefined reference to `Poco::SharedLibrary::isLoaded() const'
../devel/lib/libclass_loader.so: undefined reference to `Poco::SharedLibrary::suffix[abi:cxx11]()'
../devel/lib/libclass_loader.so: undefined reference to `typeinfo for Poco::LibraryLoadException'
../devel/lib/libclass_loader.so: undefined reference to `typeinfo for Poco::LibraryAlreadyLoadedException'
../devel/lib/libclass_loader.so: undefined reference to `Poco::SharedLibrary::SharedLibrary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
../devel/lib/libclass_loader.so: undefined reference to `typeinfo for Poco::NotFoundException'
../devel/lib/libclass_loader.so: undefined reference to `Poco::SharedLibrary::unload()'

usage of multiple static variables is discouraged

I'm double-posting this issue, which shows up in pluginlib usage: ros/pluginlib#37

Using static pluginlib ClassLoader defers lib unloading to program shutdown time.
But as the order of static releases is undefined, the program might crash.

IMHO, class_loader shouldn't use a handful of unrelated static vars, but collect them within a singleton class, which is only freed when all loaded libs were unloaded.

Memory leak: meta objects not destroyed

Using the ClassLoader (version 0.4.1) via pluginlib as recommended, we could detect some memory leaks.
My guess is that metaobjects are not destroyed after they have been inserted into the "graveyard". Or did I miss something here?

Could be related: ros/pluginlib#126

See the log below. It would be nice to get another opinion.

Excerpt of log.txt:

Direct leak of 160 byte(s) in 1 object(s) allocated from:
    #0 0x7f82ba691458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458)
    #1 0x7f82a3c28f4e in void class_loader::impl::registerPlugin<prbt_manipulator::IKFastKinematicsPlugin, kinematics::KinematicsBase>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/ros/melodic/include/class_loader/class_loader_core.hpp:205
    #2 0x7f82a3b12d20 in ProxyExec0 /home/rosuser/catkin_ws/src/pilz_robots/prbt_ikfast_manipulator_plugin/src/prbt_manipulator_ikfast_moveit_plugin.cpp:1401
    #3 0x7f82a3b130f3 in __static_initialization_and_destruction_0 /home/rosuser/catkin_ws/src/pilz_robots/prbt_ikfast_manipulator_plugin/src/prbt_manipulator_ikfast_moveit_plugin.cpp:1401
    #4 0x7f82a3b1310e in _GLOBAL__sub_I_prbt_manipulator_ikfast_moveit_plugin.cpp /home/rosuser/catkin_ws/src/pilz_robots/prbt_ikfast_manipulator_plugin/src/prbt_manipulator_ikfast_moveit_plugin.cpp:1401
    #5 0x7f82bb57c732  (/lib64/ld-linux-x86-64.so.2+0x10732)

Indirect leak of 79 byte(s) in 1 object(s) allocated from:
    #0 0x7f82ba691458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458)
    #1 0x7f82b8795bc6 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x124bc6)

Indirect leak of 68 byte(s) in 2 object(s) allocated from:
    #0 0x7f82ba691458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458)
    #1 0x7f82b9e6db6c  (/opt/ros/melodic/lib/libclass_loader.so+0x17b6c)

Indirect leak of 31 byte(s) in 1 object(s) allocated from:
    #0 0x7f82ba691458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458)
    #1 0x7f82ba36c3e2 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) /usr/include/c++/7/bits/basic_string.tcc:219
    #2 0x7f82a3c3f1e7 in class_loader::impl::AbstractMetaObject<kinematics::KinematicsBase>::AbstractMetaObject(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/ros/melodic/include/class_loader/meta_object.hpp:155
    #3 0x7f82a3c32f64 in class_loader::impl::MetaObject<prbt_manipulator::IKFastKinematicsPlugin, kinematics::KinematicsBase>::MetaObject(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/ros/melodic/include/class_loader/meta_object.hpp:186
    #4 0x7f82a3c28f6a in void class_loader::impl::registerPlugin<prbt_manipulator::IKFastKinematicsPlugin, kinematics::KinematicsBase>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/ros/melodic/include/class_loader/class_loader_core.hpp:205
    #5 0x7f82a3b12d20 in ProxyExec0 /home/rosuser/catkin_ws/src/pilz_robots/prbt_ikfast_manipulator_plugin/src/prbt_manipulator_ikfast_moveit_plugin.cpp:1401
    #6 0x7f82a3b130f3 in __static_initialization_and_destruction_0 /home/rosuser/catkin_ws/src/pilz_robots/prbt_ikfast_manipulator_plugin/src/prbt_manipulator_ikfast_moveit_plugin.cpp:1401
    #7 0x7f82a3b1310e in _GLOBAL__sub_I_prbt_manipulator_ikfast_moveit_plugin.cpp /home/rosuser/catkin_ws/src/pilz_robots/prbt_ikfast_manipulator_plugin/src/prbt_manipulator_ikfast_moveit_plugin.cpp:1401
    #8 0x7f82bb57c732  (/lib64/ld-linux-x86-64.so.2+0x10732)

Indirect leak of 8 byte(s) in 1 object(s) allocated from:
    #0 0x7f82ba691458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458)
    #1 0x7f82b9e6e383 in void std::vector<class_loader::ClassLoader*, std::allocator<class_loader::ClassLoader*> >::_M_realloc_insert<class_loader::ClassLoader* const&>(__gnu_cxx::__normal_iterator<class_loader::ClassLoader**, std::vector<class_loader::ClassLoader*, std::allocator<class_loader::ClassLoader*> > >, class_loader::ClassLoader* const&) (/opt/ros/melodic/lib/libclass_loader.so+0x18383)

SUMMARY: AddressSanitizer: 346 byte(s) leaked in 6 allocation(s).

ClassLoaderTest.threadSafety test is noisy

http://build.ros2.org/view/Eci/job/Eci__nightly-release_ubuntu_bionic_amd64/lastCompletedBuild/consoleText
ClassLoaderTest.threadSafety test emits lots of output. This should maybe be reduced:

7:  - /tmp/ws/build_isolated/class_loader/test/class_loader_utest --gtest_output=xml:/tmp/ws/test_results/class_loader/class_loader_utest.gtest.xml
7: [==========] Running 13 tests from 2 test cases.
7: [----------] Global test environment set-up.
7: [----------] 9 tests from ClassLoaderTest
7: [ RUN      ] ClassLoaderTest.basicLoad
7: Meow
7: [       OK ] ClassLoaderTest.basicLoad (1 ms)
7: [ RUN      ] ClassLoaderTest.correctNonLazyLoadUnload
7: [       OK ] ClassLoaderTest.correctNonLazyLoadUnload (0 ms)
7: [ RUN      ] ClassLoaderTest.correctLazyLoadUnload
7: [       OK ] ClassLoaderTest.correctLazyLoadUnload (0 ms)
7: [ RUN      ] ClassLoaderTest.nonExistentPlugin
7: Error:   class_loader.impl: No metaobject exists for class type Bear.
7:          at line 266 in /tmp/ws/src/ros/class_loader/test/../include/class_loader/class_loader_core.hpp
7: [       OK ] ClassLoaderTest.nonExistentPlugin (0 ms)
7: [ RUN      ] ClassLoaderTest.nonExistentLibrary
7: [       OK ] ClassLoaderTest.nonExistentLibrary (3 ms)
7: [ RUN      ] ClassLoaderTest.invalidBase
7: [       OK ] ClassLoaderTest.invalidBase (0 ms)
7: [ RUN      ] ClassLoaderTest.threadSafety
7: Meow
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Meow
7: Moooo
7: Bark
7: Meow
7: Meow
7: Meow
7: Meow
7: Meow
7: Bark
7: Moooo
7: Quack
7: Meow
7: Baaah
7: Bark
7: Meow
7: Meow
7: Moooo
7: Bark
7: Quack
7: Quack
7: Meow
7: Baaah
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Bark
7: Meow
7: Meow
7: Meow
7: Moooo
7: Bark
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Quack
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Meow
7: Moooo
7: Bark
7: Quack
7: Meow
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Meow
7: Moooo
7: Meow
7: Moooo
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Bark
7: Quack
7: Moooo
7: Bark
7: Meow
7: Moooo
7: Bark
7: Quack
7: Moooo
7: Baaah
7: Bark
7: Bark
7: Quack
7: Meow
7: Moooo
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Moooo
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Quack
7: Baaah
7: Moooo
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Meow
7: Quack
7: Baaah
7: Bark
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Baaah
7: Bark
7: Quack
7: Quack
7: Moooo
7: Baaah
7: Meow
7: Bark
7: Meow
7: Moooo
7: Meow
7: Meow
7: Bark
7: Baaah
7: Quack
7: Meow
7: Meow
7: Baaah
7: Meow
7: Bark
7: Meow
7: Quack
7: Meow
7: Baaah
7: Meow
7: Moooo
7: Moooo
7: Moooo
7: Meow
7: Meow
7: Moooo
7: Quack
7: Moooo
7: Baaah
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Bark
7: Quack
7: Bark
7: Quack
7: Baaah
7: Moooo
7: Quack
7: Meow
7: Bark
7: Baaah
7: Meow
7: Moooo
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Bark
7: Quack
7: Quack
7: Bark
7: Baaah
7: Moooo
7: Meow
7: Quack
7: Bark
7: Moooo
7: Bark
7: Baaah
7: Moooo
7: Quack
7: Bark
7: Bark
7: Baaah
7: Quack
7: Moooo
7: Baaah
7: Quack
7: Bark
7: Baaah
7: Quack
7: Moooo
7: Baaah
7: Bark
7: Moooo
7: Quack
7: Quack
7: Bark
7: Baaah
7: Meow
7: Baaah
7: Quack
7: Moooo
7: Baaah
7: Bark
7: Bark
7: Quack
7: Moooo
7: Baaah
7: Moooo
7: Quack
7: Bark
7: Bark
7: Quack
7: Baaah
7: Quack
7: Baaah
7: Bark
7: Moooo
7: Bark
7: Quack
7: Quack
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Bark
7: Baaah
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Bark
7: Baaah
7: Quack
7: Bark
7: Quack
7: Baaah
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Quack
7: Baaah
7: Baaah
7: Bark
7: Quack
7: Bark
7: Baaah
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Moooo
7: Baaah
7: Bark
7: Bark
7: Quack
7: Meow
7: Quack
7: Meow
7: Baaah
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Quack
7: Moooo
7: Baaah
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Bark
7: Quack
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Meow
7: Quack
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Meow
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Bark
7: Quack
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Moooo
7: Bark
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Meow
7: Moooo
7: Quack
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Quack
7: Baaah
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Bark
7: Moooo
7: Bark
7: Quack
7: Quack
7: Baaah
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Quack
7: Moooo
7: Bark
7: Baaah
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Bark
7: Moooo
7: Quack
7: Baaah
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: Meow
7: Moooo
7: Bark
7: Quack
7: Baaah
7: [       OK ] ClassLoaderTest.threadSafety (14 ms)
7: [ RUN      ] ClassLoaderTest.loadRefCountingNonLazy
7: [       OK ] ClassLoaderTest.loadRefCountingNonLazy (0 ms)
7: [ RUN      ] ClassLoaderTest.loadRefCountingLazy
7: [       OK ] ClassLoaderTest.loadRefCountingLazy (0 ms)
7: [----------] 9 tests from ClassLoaderTest (18 ms total)

can't use ros1 and ros2 class_loader

while developing rosbag2, we encountered that we have cyclic dependencies when trying to use ROS1 and ROS2 packages which both use their form of class loader. We worked around that by excluding "nodelets" from the ros1_bridge (as nodelets bring the dependency of class_loader).

see ros2/ros1_bridge#152

The original issue and description can be found here: ros2/rosbag2#69

fails when executing catkin_make on RPi Zerp

Hi,

Any idea what am I missing?

catkin_make -DCATKIN_WHITELIST_PACKAGES="class_loader"
Base path: /home/pi/ros_catkin_ws
Source space: /home/pi/ros_catkin_ws/src
Build space: /home/pi/ros_catkin_ws/build
Devel space: /home/pi/ros_catkin_ws/devel
Install space: /home/pi/ros_catkin_ws/install
####
#### Running command: "make cmake_check_build_system" in "/home/pi/ros_catkin_ws/build"
####
####
#### Running command: "make -j1 -l1" in "/home/pi/ros_catkin_ws/build"
####
[ 20%] Building CXX object class_loader/CMakeFiles/class_loader.dir/src/class_loader.cpp.o
In file included from /home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader.hpp:46:0,
                 from /home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp:30:
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp: In function ‘void class_loader::impl::registerPlugin(const string&, const string&)’:
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:181:45: error: there are no arguments to ‘CONSOLE_BRIDGE_logDebug’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logDebug’ must be available [-fpermissive]
     getCurrentlyLoadingLibraryName().c_str());
                                             ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:181:45: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:199:79: error: there are no arguments to ‘CONSOLE_BRIDGE_logDebug’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logDebug’ must be available [-fpermissive]
       "Please refactor your code to isolate plugins into their own libraries.");
                                                                               ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:222:25: error: there are no arguments to ‘CONSOLE_BRIDGE_logWarn’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logWarn’ must be available [-fpermissive]
       class_name.c_str());
                         ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:230:62: error: there are no arguments to ‘CONSOLE_BRIDGE_logDebug’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logDebug’ must be available [-fpermissive]
     class_name.c_str(), reinterpret_cast<void *>(new_factory));
                                                              ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp: In function ‘Base* class_loader::impl::createInstance(const string&, class_loader::ClassLoader*)’:
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:250:95: error: there are no arguments to ‘CONSOLE_BRIDGE_logError’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logError’ must be available [-fpermissive]
       "class_loader.impl: No metaobject exists for class type %s.", derived_class_name.c_str());
                                                                                               ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:270:44: error: there are no arguments to ‘CONSOLE_BRIDGE_logDebug’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logDebug’ must be available [-fpermissive]
         "possible to shutdown the library!");
                                            ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:281:56: error: there are no arguments to ‘CONSOLE_BRIDGE_logDebug’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logDebug’ must be available [-fpermissive]
     (typeid(obj).name()), reinterpret_cast<void *>(obj));
                                                        ^
In file included from /home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp:30:0:
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader.hpp: In member function ‘void class_loader::ClassLoader::onPluginDeletion(Base*)’:
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader.hpp:245:36: error: there are no arguments to ‘CONSOLE_BRIDGE_logDebug’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logDebug’ must be available [-fpermissive]
       reinterpret_cast<void *>(obj));
                                    ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader.hpp:262:35: error: there are no arguments to ‘CONSOLE_BRIDGE_logWarn’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logWarn’ must be available [-fpermissive]
           getLibraryPath().c_str());
                                   ^
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader.hpp: In member function ‘Base* class_loader::ClassLoader::createRawInstance(const string&, bool)’:
/home/pi/ros_catkin_ws/src/class_loader/include/class_loader/class_loader.hpp:295:7: error: there are no arguments to ‘CONSOLE_BRIDGE_logInform’ that depend on a template parameter, so a declaration of ‘CONSOLE_BRIDGE_logInform’ must be available [-fpermissive]
       );
       ^
/home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp: In constructor ‘class_loader::ClassLoader::ClassLoader(const string&, bool)’:
/home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp:72:31: error: ‘CONSOLE_BRIDGE_logDebug’ was not declared in this scope
     this, library_path.c_str());
                               ^
/home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp: In destructor ‘virtual class_loader::ClassLoader::~ClassLoader()’:
/home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp:82:65: error: ‘CONSOLE_BRIDGE_logDebug’ was not declared in this scope
     "Destroying class loader, unloading associated library...\n");
                                                                 ^
/home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp: In member function ‘int class_loader::ClassLoader::unloadLibraryInternal(bool)’:
/home/pi/ros_catkin_ws/src/class_loader/src/class_loader.cpp:122:70: error: ‘CONSOLE_BRIDGE_logWarn’ was not declared in this scope
       "destroying the ClassLoader. The library will NOT be unloaded.");
                                                                      ^
class_loader/CMakeFiles/class_loader.dir/build.make:62: recipe for target 'class_loader/CMakeFiles/class_loader.dir/src/class_loader.cpp.o' failed
make[2]: *** [class_loader/CMakeFiles/class_loader.dir/src/class_loader.cpp.o] Error 1
CMakeFiles/Makefile2:736: recipe for target 'class_loader/CMakeFiles/class_loader.dir/all' failed
make[1]: *** [class_loader/CMakeFiles/class_loader.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2

Unnecessary conditional judgment in isLibraryLoaded ?

I wonder num_meta_objs_for_lib_bound_to_loader will always less than num_meta_objs_for_lib, because num_meta_objs_for_lib_bound_to_loader is look forward in allMetaObjectsForLibrary(library_path) and

num_meta_objs_for_lib is equal with allMetaObjectsForLibrary(library_path).size()

bool isLibraryLoaded(const std::string & library_path, ClassLoader * loader)
{
bool is_lib_loaded_by_anyone = isLibraryLoadedByAnybody(library_path);
size_t num_meta_objs_for_lib = allMetaObjectsForLibrary(library_path).size();
size_t num_meta_objs_for_lib_bound_to_loader =
allMetaObjectsForLibraryOwnedBy(library_path, loader).size();
bool are_meta_objs_bound_to_loader =
(0 == num_meta_objs_for_lib) ? true : (
num_meta_objs_for_lib_bound_to_loader <= num_meta_objs_for_lib);

Link error with Poco when using libc++

Ubuntu Focal / Cmake 3.16.3 / Clang 11 / Foxy Master

--- stderr: class_loader                                                                   
ld.lld: error: ../../libclass_loader.so: undefined reference to Poco::SharedLibrary::SharedLibrary(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [test/fviz_case_study/CMakeFiles/class_loader_Test_Fviz_Main.dir/build.make:90: test/fviz_case_study/class_loader_Test_Fviz_Main] Error 1
make[1]: *** [CMakeFiles/Makefile2:403: test/fviz_case_study/CMakeFiles/class_loader_Test_Fviz_Main.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:141: all] Error 2
---
Failed   <<< class_loader	[ Exited with code 2 ]

Migrate FindPoco.cmake to cmake_modules

I was looking to potentially use the Poco library in one of my projects and I noticed that class_loader has it's own private copy of FindPoco. Is there any reason for this or can it be migrated to cmake_modules?

[ros2] poco 1.7.8 on macosx - undefined symbols

I am compiling against the ROS2 branch.

Undefined symbols for architecture x86_64:
  "Poco::SharedLibrary::suffix()", referenced from:
      class_loader::systemLibrarySuffix() in class_loader.cpp.o
  "Poco::SharedLibrary::unload()", referenced from:
      class_loader::impl::unloadLibrary(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, class_loader::ClassLoader*) in class_loader_core.cpp.o
  "Poco::SharedLibrary::SharedLibrary(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      class_loader::impl::loadLibrary(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, class_loader::ClassLoader*) in class_loader_core.cpp.o
  "Poco::SharedLibrary::isLoaded() const", referenced from:
      class_loader::impl::isLibraryLoadedByAnybody(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in class_loader_core.cpp.o
      class_loader::impl::unloadLibrary(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, class_loader::ClassLoader*) in class_loader_core.cpp.o
  "typeinfo for Poco::RuntimeException", referenced from:
      GCC_except_table47 in class_loader_core.cpp.o
  "typeinfo for Poco::NotFoundException", referenced from:
      GCC_except_table41 in class_loader_core.cpp.o
  "typeinfo for Poco::LibraryLoadException", referenced from:
      GCC_except_table41 in class_loader_core.cpp.o
  "typeinfo for Poco::LibraryAlreadyLoadedException", referenced from:
      GCC_except_table41 in class_loader_core.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libclass_loader.dylib] Error 1
make[1]: *** [CMakeFiles/class_loader.dir/all] Error 2
make: *** [all] Error 2

Is load_ref_count_ no need to count number?

There is a lock load_ref_lock and class_loader::impl::loadLibrary(getLibraryPath(), this) will not load .so library twice. Why not just use a bool is_loaded to load and unload the .so library.

I didn't see the benefits of counting times of the loadLibrary. The unloadLibrary will do nothing when load_ref_count_ > 0 too.

boost::recursive_mutex::scoped_lock lock(load_ref_count_mutex_);
load_ref_count_ = load_ref_count_ + 1;
class_loader::impl::loadLibrary(getLibraryPath(), this);

[ros2] ‘placeholders’ is not a namespace-name - missing include

ros2 branch, using gcc-7.1.1 (ArchLinux):

.../class_loader/include/class_loader/class_loader.h:128:26: error: ‘placeholders’ is not a namespace-name
     using namespace std::placeholders;

in include/class_loader/class_loader.h there's a missing include, adding it fixed the compilation error:

#include <functional>

It's possible that in previous versions of gcc functional was included in other libraries used here, but now it's not the case.

class_loader generating compilation errors

Hello.

I'm trying to install ROS Jade on macOS 10.12.1, using clang++ and libc++, but I keep getting the following error when trying to compile ROS (packages as nodelet_math_tutorial or rqt_gui). The compiler says there's no definition of several variables in the global namespace and the stack traces seem to point that the problem is coming from class_loader. You can see the output here. I have tried several approaches, such as changing from libc++ to libstdc++, but then its deprecated and some other packages fail. I thought initially it was a problem that I could solve in each of the packages, so I posted in common_tutorials, but then they pointed me in this direction. I hope you can help me with this!!

Thanks

undefined reference to `class_loader

--- stderr: hardware_interface
/usr/bin/ld: libhardware_interface.so: undefined reference to `class_loader::ClassLoader::isLibraryLoaded()'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::package::getPath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `class_loader::systemLibrarySuffix[abi:cxx11]()'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::console::initialize()'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::console::initializeLogLocation(ros::console::LogLocation*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ros::console::levels::Level)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::console::print(ros::console::FilterBase*, void*, ros::console::levels::Level, char const*, int, char const*, char const*, ...)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `boost::filesystem::path::filename() const'
/usr/bin/ld: libhardware_interface.so: undefined reference to `class_loader::MultiLibraryClassLoader::getAllAvailableClassLoaders()'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::console::setLogLocationLevel(ros::console::LogLocation*, ros::console::levels::Level)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::console::g_initialized'
/usr/bin/ld: libhardware_interface.so: undefined reference to `class_loader::MultiLibraryClassLoader::getRegisteredLibraries[abi:cxx11]()'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::console::checkLogLocationEnabled(ros::console::LogLocation*)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `ros::package::getPlugins(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, bool)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `boost::filesystem::path::operator/=(boost::filesystem::path const&)'
/usr/bin/ld: libhardware_interface.so: undefined reference to `boost::filesystem::path::parent_path() const'
/usr/bin/ld: libhardware_interface.so: undefined reference to `class_loader::impl::AbstractMetaObjectBase::isOwnedBy(class_loader::ClassLoader const*)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test_generic_system.dir/build.make:128: test_generic_system] Error 1
make[1]: *** [CMakeFiles/Makefile2:146: CMakeFiles/test_generic_system.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:141: all] Error 2
---
Failed   <<< hardware_interface [15.7s, exited with code 2]
Aborted  <<< moveit_msgs [26.0s]
Aborted  <<< controller_manager_msgs [37.3s]
Aborted  <<< geometric_shapes [1min 12s]

Summary: 2 packages finished [1min 12s]
  1 package failed: hardware_interface
  3 packages aborted: controller_manager_msgs geometric_shapes moveit_msgs
  3 packages had stderr output: geometric_shapes hardware_interface moveit_msgs
  48 packages not processed

How to resolve this issue I am unable to resolve

segmentation fault in class_loader

After compiling pluginlib, class_loader and rviz from source, I can start rviz without any problems. However, if rviz loads an image display (that uses an image_transport_plugin) during start-up, it get the following segfault:

127 jkammerl@rbh ~/RVIZ ./devel/lib/rviz/rviz
[ INFO] [1358555603.751587156]: rviz version 1.9.19
[ INFO] [1358555603.751644412]: compiled against OGRE version 1.7.4 (Cthugha)
[ERROR] [1358555606.537876326]: PluginlibFactory: The plugin for class 'moveit_rviz_plugin/PlanningScene' failed to load. Error: According to the loaded plugin descriptions the class moveit_rviz_plugin/PlanningScene with base class type rviz::Display does not exist. Declared types are rviz/Axes rviz/Camera rviz/DepthCloud rviz/Grid rviz/GridCells rviz/Image rviz/InteractiveMarkers rviz/LaserScan rviz/Map rviz/Marker rviz/MarkerArray rviz/Odometry rviz/Path rviz/PointCloud rviz/PointCloud2 rviz/Polygon rviz/Pose rviz/PoseArray rviz/Range rviz/RobotModel rviz/TF rviz_plugin_tutorials/Imu
[ERROR] [1358555606.546112029]: PluginlibFactory: The plugin for class 'moveit_rviz_plugin/MotionPlanning' failed to load. Error: According to the loaded plugin descriptions the class moveit_rviz_plugin/MotionPlanning with base class type rviz::Display does not exist. Declared types are rviz/Axes rviz/Camera rviz/DepthCloud rviz/Grid rviz/GridCells rviz/Image rviz/InteractiveMarkers rviz/LaserScan rviz/Map rviz/Marker rviz/MarkerArray rviz/Odometry rviz/Path rviz/PointCloud rviz/PointCloud2 rviz/Polygon rviz/Pose rviz/PoseArray rviz/Range rviz/RobotModel rviz/TF rviz_plugin_tutorials/Imu
[ INFO] [1358555606.841140209]: pluginlib WARNING: PLUGINLIB_DECLARE_CLASS is deprecated, please use PLUGINLIB_EXPORT_CLASS instead. You can run the script 'plugin_macro_update' provided with pluginlib in your package source folder to automatically and recursively update legacy macros.
[ INFO] [1358555606.841251691]: pluginlib WARNING: PLUGINLIB_DECLARE_CLASS is deprecated, please use PLUGINLIB_EXPORT_CLASS instead. You can run the script 'plugin_macro_update' provided with pluginlib in your package source folder to automatically and recursively update legacy macros.
[ INFO] [1358555606.841385722]: class_loader::ClassLoader: An attempt is being made to create a managed plugin instance (i.e. boost::shared_ptr), however an unmanaged instance was created within this process address space. This means libraries for the managed instances will not be shutdown automatically on final plugin destruction if on demand (lazy) loading/unloading mode is used.
[1] 12093 segmentation fault (core dumped) ./devel/lib/rviz/rviz

Intermittent Failure to Load Library Under High Thread Contention

This issue is related to the one I opened up against pluginlib, found here. For context, I am running Ubuntu 14.04 and ROS-Indigo. I am writing an application that (for better or worse) ends up loading dozens of plugins per thread across up to several hundred threads. In the process of this development, the loading of plugins has become an issue. I can fix my issue by serializing the construction of plugins in my code, but I'd like to get it at the source. Pluginlib has its own issues, but it appears that (at least some of) the problem extends to this library.

I can produce occasional crashes under high contention with the following code:

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/ref.hpp>

#include <class_loader/class_loader.h>
#include <pluginlib_tutorials/polygon_base.h>

typedef boost::shared_ptr<polygon_base::RegularPolygon> RegularPolygonPtr;

// Experiment 1: Each worker has its own class loader
void workerThread1(const std::string& library_path, const std::string& class_name, int n)
{
  class_loader::ClassLoader loader (library_path);
  std::vector<RegularPolygonPtr> plugins;

  for (int i = 0; i < n; ++i)
  {
    RegularPolygonPtr plugin = loader.createInstance<polygon_base::RegularPolygon>(class_name);
    if (plugin)
      plugin->initialize(10.0);
    else
      std::cerr << "ERROR\n";
    plugins.push_back(plugin);
  }

  boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}

void launchExperiment1(const std::string& lib_path, const std::string& class_name, int n_threads, int n)
{
  std::vector<boost::thread*> threads;
  for (int i = 0; i < n_threads; ++i)
  {
    threads.push_back( new boost::thread(workerThread1, lib_path, class_name, n) );
  }

  for (int i = 0; i < n_threads; ++i)
  {
    threads[i]->join();
    delete threads[i];
  }
}

int main(int argc, char** argv)
{
  if (argc < 4)
  {
    std::cerr << "Usage: rosrun polygon_class_loader <path_to_library> <n_threads> <n_items_per_thread>\n";
    return 1;
  }

  const std::string library_path (argv[1]);
  class_loader::ClassLoader loader(library_path);
  std::vector<std::string> classes = loader.getAvailableClasses<polygon_base::RegularPolygon>();

  if (classes.empty())
  {
    std::cerr << "No available plugins in this library\n";
    return 2;
  }

  const std::string& class_to_load = classes.front();
  std::cout << "Choosing to load many instances of " << class_to_load << "\n";

  boost::this_thread::sleep(boost::posix_time::milliseconds(500));

  int n_threads = std::atoi(argv[2]);
  int n_items_per_thread = std::atoi(argv[3]);

  std::cout << "Starting multi-threaded loading experiment w/ " << n_threads << " threads " <<
            "and " << n_items_per_thread << " plugins per thread" << std::endl;

  std::cout << "Experiment 1: All threads have own class loader" << std::endl;
  launchExperiment1(library_path, class_to_load, n_threads, n_items_per_thread);
}

Drop this into the pluginlib tutorial package and build. Run with roscore and run with the following extra arguments 4000 100 which indicates 4000 threads loading 100 plugins a piece. It doesn't always trip an error, so try it a few times.

I frequently observe the following error in the middle of the run:

terminate called after throwing an instance of 'class_loader::CreateClassException'
  what():  Could not create instance of type polygon_plugins::Square
Aborted (core dumped)

This exception is coming from here. Some testing shows that a factory does exist when the plugin is created, but it's not owned by either requesting class loader or NULL.

Digging around, sure enough, it would appear that the underlying vector that keeps a list of the "owners" of class loader is not protected. Concurrent access can happen here and here for example.

Putting a lock in part of loadLibrary appears to make the crash go away. Ala:

  //If it's already open, just update existing metaobjects to have an additional owner.
  if(isLibraryLoadedByAnybody(library_path))
  {
    boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
    logDebug("class_loader.class_loader_private: Library already in memory, but binding existing MetaObjects to loader if necesesary.\n");
    addClassLoaderOwnerForAllExistingMetaObjectsForLibrary(library_path, loader);
    return;
  }

I'll submit a PR unless there's an objection. @mikaelarguedas.

Notes on `RTLD_GLOBAL` in the code ?

I found below notes in code. It say RTLD_GLOBAL will cause static global variable initialization problem when reopen the library.

I try load and unload the library, and the static variable is int correct. I don't know under what circumstances the problem will occur ? In fact, I found that some static variables in template classes and inline functions will cause this problem. I did not find these situations in the code.

// Insert into graveyard
// We remove the metaobject from its factory map, but we don't destroy it...instead it
// saved to a "graveyard" to the side.
// This is due to our static global variable initialization problem that causes factories
// to not be registered when a library is closed and then reopened.
// This is because it's truly not closed due to the use of global symbol binding i.e.
// calling dlopen with RTLD_GLOBAL instead of RTLD_LOCAL.
// We require using the former as the which is required to support RTTI
insertMetaObjectIntoGraveyard(meta_obj);
} else {

I found the RTLD_NODELETE dlopen doc, dlopen not use the RTLD_NODELETE option, I also make some test that static variable inited correctly.

RTLD_NODELETE (since glibc 2.2)
Do not unload the library during dlclose(). Consequently, the library's static variables are not reinitialized if the library is reloaded with dlopen() at a later time. This flag is not specified in POSIX.1-2001.

Package not configuring

Hey,
although declared as stand alone, the CMakeLists.txt contains an install target called PROGRAMS, the cmake configure phase thus can't complete (because the target PROGRAMS is not declared in non-ros installations). We're using the class_loader in ROCK.

mac ros build class_loader issue

-- Generating done -- Build files have been written to: /Users/liu/ros_catkin_ws/build_isolated/class_loader ==> make -j8 -l8 in '/Users/liu/ros_catkin_ws/build_isolated/class_loader' Scanning dependencies of target class_loader [ 60%] Building CXX object CMakeFiles/class_loader.dir/src/meta_object.cpp.o [ 60%] Building CXX object CMakeFiles/class_loader.dir/src/class_loader.cpp.o [ 60%] Building CXX object CMakeFiles/class_loader.dir/src/class_loader_core.cpp.o [ 80%] Building CXX object CMakeFiles/class_loader.dir/src/multi_library_class_loader.cpp.o In file included from /Users/liu/ros_catkin_ws/src/class_loader/src/class_loader_core.cpp:30: In file included from /Users/liu/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:43: In file included from /usr/local/include/Poco/SharedLibrary.h:29: In file included from /usr/local/include/Poco/SharedLibrary_UNIX.h:22: In file included from /usr/local/include/Poco/Mutex.h:22: /usr/local/include/Poco/Exception.h:46:2: error: exception specification of overriding function is more lax than base version ~Exception() noexcept; ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:101:13: note: overridden virtual function is here virtual ~exception() _NOEXCEPT; ^ In file included from /Users/liu/ros_catkin_ws/src/class_loader/src/class_loader_core.cpp:30: In file included from /Users/liu/ros_catkin_ws/src/class_loader/include/class_loader/class_loader_core.hpp:43: In file included from /usr/local/include/Poco/SharedLibrary.h:29: In file included from /usr/local/include/Poco/SharedLibrary_UNIX.h:22: In file included from /usr/local/include/Poco/Mutex.h:22: /usr/local/include/Poco/Exception.h:46:14: error: expected ';' at end of declaration list ~Exception() noexcept; ^ /usr/local/include/Poco/Exception.h:52:34: error: expected ';' at end of declaration list virtual const char* name() const noexcept; ^ /usr/local/include/Poco/Exception.h:55:39: error: expected ';' at end of declaration list virtual const char* className() const noexcept; ^

Question: How to load library when dependencies are not in the LD_LIBRARY_PATH?

I am currently releasing some visualization tools leveraging snap packages where they can be loaded dynamically using class_loader. In order for this to work correctly because the libraries dependencies are inside the snap packages folder and not in the LD_LIBRARY_PATH it fails to load. Now if I manually add the snap package path to the LD_LIBRARY_PATH it loads fine, but not a great solution because if globally added this could cause issues with other libraries using the snap packages resources. Does anyone have any ideas?

ROS independent builds with rolling release?

According to https://github.com/ros/class_loader/blob/rolling/README.md

The class_loader package is a ROS-independent package for loading plugins

However, currently it depends on rcpputils and recursively on rcutils, apparently only for the rcpputils::SharedLibrary class. Are there plans to make this dependency optional (or remove it)?

Additionally, it would help to make the find_package(console_bridge_vendor REQUIRED) optional (simply removing that line does not hurt, if some working console_bridge implementation is installed).

SEVERE WARNING!!! in tests

The MultiClassLoaderTest.noWarningOnLazyLoad test case produces a scary looking warning.

Judging by the name of the case, (1) the warning should not happen (2) the test case is broken for failing to detect this warning.

7: [ RUN      ] MultiClassLoaderTest.noWarningOnLazyLoad
7: Warning: class_loader.ClassLoader: SEVERE WARNING!!! Attempting to unload library while objects created by this loader exist in the heap! You should delete your objects before attempting to unload the library or destroying the ClassLoader. The library will NOT be unloaded.
7:          at line 158 in /tmp/ws/src/ros/class_loader/src/class_loader.cpp
7: Warning: class_loader.ClassLoader: SEVERE WARNING!!! Attempting to unload library while objects created by this loader exist in the heap! You should delete your objects before attempting to unload the library or destroying the ClassLoader. The library will NOT be unloaded.
7:          at line 158 in /tmp/ws/src/ros/class_loader/src/class_loader.cpp
7: Meow
7: Bark
7: Beep boop
7: [       OK ] MultiClassLoaderTest.noWarningOnLazyLoad (0 ms)

Jenkins build failed?

Looks like the Jenkins build failed: http://jenkins.ros.org/job/devel-groovy-class_loader/ARCH_PARAM=amd64,UBUNTU_PARAM=precise,label=devel/lastBuild/console

Here's the place where the error occurred (processing triggers):

Setting up python-rosinstall (0.6.29-1) ...
Processing triggers for python-support ...
Parsing rosdistro file for groovy
devel script failed. Check out the console output above for details.
Traceback (most recent call last):
  File "/home/rosbuild/hudson/workspace/devel-groovy-class_loader/ARCH_PARAM/amd64/UBUNTU_PARAM/precise/label/devel/jenkins_scripts/devel", line 30, in <module>
    main()
  File "/home/rosbuild/hudson/workspace/devel-groovy-class_loader/ARCH_PARAM/amd64/UBUNTU_PARAM/precise/label/devel/jenkins_scripts/devel", line 24, in main
    build_in_workspace=options.build_in_workspace, sudo=options.sudo)
  File "/home/rosbuild/hudson/workspace/devel-groovy-class_loader/ARCH_PARAM/amd64/UBUNTU_PARAM/precise/label/devel/jenkins_scripts/test_repositories.py", line 59, in test_repositories
    sudo, no_chroot)
  File "/home/rosbuild/hudson/workspace/devel-groovy-class_loader/ARCH_PARAM/amd64/UBUNTU_PARAM/precise/label/devel/jenkins_scripts/test_repositories.py", line 76, in _test_repositories
    release = get_cached_release(index, ros_distro)
  File "/usr/lib/pymodules/python2.7/rosdistro/__init__.py", line 115, in get_cached_release
    cache = get_release_cache(index, dist_name)
  File "/usr/lib/pymodules/python2.7/rosdistro/__init__.py", line 151, in get_release_cache
    yaml_gz_str = load_url(url)
  File "/usr/lib/pymodules/python2.7/rosdistro/loader.py", line 41, in load_url
    fh = urllib2.urlopen(url, timeout=timeout)
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1207, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1180, in do_open
    r = h.getresponse(buffering=True)
  File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse
    response.begin()
  File "/usr/lib/python2.7/httplib.py", line 407, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 365, in _read_status
    line = self.fp.readline()
  File "/usr/lib/python2.7/socket.py", line 447, in readline
    data = self._sock.recv(self._rbufsize)
socket.timeout: timed out

Who should this error report go to?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.