ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org

# Error in rosconsole when running GigE camera

I'm trying to wrap the driver to our Basler GigE camera in ROS, but get the following error at runtime:

 Basler_camera: /usr/include/boost/regex/v4/match_results.hpp:503: void boost::match_results<BidiIterator, Allocator>::set_first(BidiIterator) [with BidiIterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, Allocator = std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> > > >]: Assertion m_subs.size() > 2' failed.
Aborted


Debugging with gdb gave the following traceback:

#0  0xb7fe1424 in __kernel_vsyscall ()
#1  0xb783be71 in raise () from /lib/i386-linux-gnu/libc.so.6
#2  0xb783f34e in abort () from /lib/i386-linux-gnu/libc.so.6
#3  0xb7834888 in __assert_fail () from /lib/i386-linux-gnu/libc.so.6
#4  0xb7fa975c in set_first (this=0xbfffe384)
at /usr/include/boost/regex/v4/match_results.hpp:503
#5  boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_prefix (this=0xbfffe384)
at /usr/include/boost/regex/v4/perl_matcher_common.hpp:321
#6  0xb7d7955a in boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::find_restart_any (this=0xbfffe384)
at /usr/include/boost/regex/v4/perl_matcher_common.hpp:771
#7  0xb7d77220 in boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::find_imp (this=0xbfffe384)
at /usr/include/boost/regex/v4/perl_matcher_common.hpp:300
#8  0xb7d77715 in find (first=..., last=..., m=..., e=...,
flags=boost::regex_constants::match_default, base=...)
at /usr/include/boost/regex/v4/perl_matcher_common.hpp:230
#9  boost::regex_search<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char> >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char> > > >, char, boost::regex_traits<char> > (first=..., last=...,
m=..., e=..., flags=boost::regex_constants::match_default, base=...)
at /usr/include/boost/regex/v4/regex_search.hpp:56
#10 0xb7d7778d in boost::regex_search<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char> >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char> > > >, char, boost::regex_traits<char> > (
first=..., last=..., m=..., e=..., flags=boost::regex_constants::match_default)
at /usr/include/boost/regex/v4/regex_search.hpp:42
#11 0xb7d778ea in ros::console::Formatter::init (this=0xb7d85380,
fmt=0xb7d7c644 "[${severity}] [${time}]: \${message}")
at /tmp/buildd/ros-diamondback-ros-comm-1.4.7/debian/ros-diamondback-ros-comm/opt/ros/diamondback/stacks/ros_comm/tools/rosconsole/src/rosconsole/rosconsole.cpp:282
#12 0xb7d6e004 in ros::console::do_initialize ()
at /tmp/buildd/ros-diamondback-ros-comm-1.4.7/debian/ros-diamondback-ros-comm/opt/ros/diamondback/stacks/ros_comm/tools/rosconsole/src/rosconsole/rosconsole.cpp:417
#13 0xb7d6e49c in ros::console::initialize ()
at /tmp/buildd/ros-diamondback-ros-comm-1.4.7/debian/ros-diamondback-ros-comm/opt/ros/diamondback/stacks/ros_comm/tools/rosconsole/src/rosconsole/rosconsole.cpp:429
#14 0xb7d6e7f9 in StaticInit ()
at /tmp/buildd/ros-diamondback-ros-comm-1.4.7/debian/ros-diamondback-ros-comm/opt/ros/diamondback/stacks/ros_comm/tools/rosconsole/src/rosconsole/rosconsole.cpp:676
#15 ...
edit retag close merge delete

Sort by » oldest newest most voted

I found out that the problem is with different versions of Boost. The driver from Basler works with Boost 1.38, but not 1.42 which is the version used by ROS. The manufacturer also seems reluctant to include support for newer versions of Boost in their diver.

/Ola

more

Hi Ola,

Thank you for raising this issue on ROS answers.

I have confirmed that this is indeed a Boost issue, and decided to 'take the red pill' to find the root cause...

Pylon statically links against some Boost libraries that are also linked into your ROS node by rosbuild. The issue here is that the statically linked Boost symbols are exposed in the dynamic symbol table of the Pylon driver (libpylonbase.so), and these collide with the system library symbols. The linker will always use the first loaded symbol, which depends on the order in which ld.so loads the libraries.

When ROS used Boost 1.38 everything was fine because the linker could find every required Boost symbol in either one of the library versions (depending on which was loaded first) - i.e. all symbols would be bound to either Pylon's statically linked version, or the system version. In this situation, all calls are ABI compatible and any stateful data in the library would remain consistent because only one library is referenced.

Of course, the Boost API typically changes between versions, so when different Boost versions are linked (e.g.: 1.38 in Pylon and 1.40 in Diamondback), the linker can no longer resolve all symbols to a single library. Here the Boost symbols common to both versions are bound to the first loaded library version, and those symbols missing in the first library are bound to the second! This is a very bad situation because even slight changes to the library can render the calls ABI incompatible (even though they are API compatible). Even if the calls are ABI compatible, any global state in the library would be in mortal danger of corruption due to unexpected calling sequences.

For me this 'bug' typically manifests itself as a segfault due to a null pointer dereference in free(), for you it manifests slightly differently, but has the same root cause.

Although the Boost libraries are 'statically' linked in libpylonbase.so, the symbols are present in the dynamic symbol table, which cannot be modified once the .so has been created (i.e. by the end-user). This means that the end-user cannot hide or obfuscate the offending Boost symbols without an obscene amount of effort. The only practical solution is for Basler to statically link a 'private' version of Boost, as suggested by this stackoverflow post.

Basler is aware of this issue:

We have verified with Basler AG that this issue is known and the problem will be fixed with a future release of Pylon.

In the meantime, the workaround will be to use v1.38 of the Boost libraries. This works fine with Pylon 2.3.

I hope you will be able to use the workaround method for now, please let us know if you have further queries.

-- excerpt of email from Basler Asia Support bc.support.asia@baslerweb.com

Of course no release date was specified, so in the short-term this does not help us write a ...

more

Hi,

I ran into the same issue and tried to find a workaround that lets you use the pylon library exactly as intended until basler comes up with a solution.

The basic idea is to rename the symbols in the affected files.

For example if we would rename a symbol from _ZTIN5boost21thread_resource_errorE to _ZTIN5BOOST21thread_resource_errorE and all references to it as well then it could easily coexist with the boost version of ROS

The problem ist that one can not simply change symbol names in an elf file because they are stored in a hash table and renaming it would result in a different hash and cause the loader to not find the specified symbol.

Fortunately the hash function is very simple and I derived similar names that cause a hash collision and thus have the same index in the hash table despite the different name.

Long story short: use the following five commands to change the symbolnames in the pylon libraries and it should be able to easily coexist with any other boost version.

cd <to your pylon installation> (i.e. cd /opt/pylon )

sudo perl -pi -e 's/5boost/5dOost/g' lib/libpylonbase-2.3.3.so
sudo perl -pi -e 's/5boost/5dOost/g' lib/libpylongigesupp-2.3.3.so
sudo perl -pi -e 's/5boost/5dOost/g' lib/pylon/tl/pyloncamemu-2.3.3.so
sudo perl -pi -e 's/5boost/5dOost/g' lib/pylon/tl/pylongige-2.3.3.so
`

I did not have time to fully test it but my ROS node can now be started without the shared_ptr exception and the pylonviewer still works (although I currently tested it only with emulated cameras)

I will update this post if I find any problems, but you are welcome to give me feedback as well.

Best regards Michael

more

I just made a (currently very, very simple) ROS package for the Aravis GigE Vision library. I'm using it with my Basler GigE camera instead of the Basler drivers because of this exact problem. See it here: http://github.com/strawlab/camera_aravis

more

Thanks for the tip! Unfortunately it did not solve my problem (but maybe future ones :-)).

more

Hi Ola (CROPS colleague!),

A few days ago I upgraded to ROS electric and there they seemed to have solved many diamondback issues. I don't know what the cause of you problem is but an upgrade to Electric + Ubuntu 11.04 might help.

Best Regards, Wouter Bac

more