Gazebo | Ignition | Community
Ask Your Question
0

Undefined symbol with plugin

asked 2018-12-13 20:06:48 -0500

david_d gravatar image

I've been stuck on this issue for an embarrassingly long period of time, and would be very grateful for any help. I'm very new to c++ and CMake, so it's likely I'm overlooking something quite obvious.

When I run Gazebo with a plugin I wrote, plank_drop.cc, I get the following error:

gzserver: symbol lookup error: /home/plugins/build/libPlankDrop.so: undefined symbol: _Z4joinIdENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS0_4listIT_SaIS7_EEES5_

The symbol's name leads me to believe the issue is in the join function, called within plank_drop.cc, and defined in the extra_functions.cc.

I've added join() to the scope of plank_drop.cc like so:

#include "extra_functions.h"

And the compiler doesn't complain. It never seems to compain at compile time, or link time. It only fails at runtime. I've set this up in my CMakeList.txt like this:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

find_package(gazebo REQUIRED)
include_directories(${GAZEBO_INCLUDE_DIRS})
link_directories(${GAZEBO_LIBRARY_DIRS})
list(APPEND CMAKE_CXX_FLAGS "${GAZEBO_CXX_FLAGS}")

add_library(PlankDrop SHARED plank_drop.cc)
add_library(CamRecord SHARED cam_record.cc)
add_library(ExtraFunctions SHARED extra_functions.cc extra_functions.h)

target_link_libraries(PlankDrop CamRecord ExtraFunctions ${GAZEBO_LIBRARIES})

The relevant parts of my source code is here. All of my solutions just introduce new issues that are equally confusing.

edit retag flag offensive close merge delete

Comments

So, following this page: http://gdwarner.blogspot.com/2009/03/c-runtime-symbol-lookup-error.html Using nm libPlankDrop.so | c++filt, this symbol is the problem: U std::__cxx11::basic_string<char, std::char_traits<char="">, std::allocator<char> > join<double>(std::__cxx11::list<double, std::allocator<double=""> >, std::__cxx11::basic_string<char, std::char_traits<char="">, std::allocator<char> >) I am still very confused.

david_d gravatar imagedavid_d ( 2018-12-13 21:02:46 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2018-12-14 16:02:20 -0500

azeey gravatar image

In C++, you usually have to define template functions inside the header file. Here is a better explanation.

Also, you might need to add GAZEBO_VISIBLE macro to your functions if you want them to be available elsewhere. This won't apply to your template classes/function though. You'll need to include gazebo/util/system.hh to get the macro.

edit flag offensive delete link more

Comments

Thank you for your help. I'd also like to thank Jordan Liviero, who made a merge request on gitlab with this solution. Unfortunately, I didn't see either until I had already figured out a workaround myself. https://gitlab.com/daviddaish/pose-pipeline/merge_requests/1

david_d gravatar imagedavid_d ( 2018-12-14 21:24:55 -0500 )edit
0

answered 2018-12-14 15:59:19 -0500

david_d gravatar image

updated 2018-12-14 16:15:57 -0500

Ok, I fixed the issue. You can see the commit that fixed it here.

What fixed it, was changing the join function from a template function, to an overloaded function. I assume this fixed it because I was misusing template functions somehow.

Side information:

  • It was failing at runtime, because it's a shared library. Shared libraries have some of the linking process done at runtime, unlike static libraries. Presumably, this means the compiler gives it some leniency at compile time, meaning it does not fail. I did not realize this, and was thoroughly confused by the idea of a c++ program failing like that at runtime. More info here.

  • The reason the symbol came out all wierd looking,(_Z4joinIdENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS0_4listIT_SaIS7_EEES5_) was because c++ was doing something called "mangling", which occurs when a function appears more than once in a single namespace. For example, when overloading a function. The symbol came out as expected when using the "nm" command with the "-C" flag, or piping it into the "c++filt" command. Learn more about mangling here.

  • Ultimately, the problem and solution revealed itself when I took a step back and took the time to learn the tools I'm using, not just randomly changing things, hoping it would fix itself. Problems that seemed bewildering and nonsensical made a great deal more sense once I took the time to carefully read the docs and man pages. Who knew?

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2018-12-13 20:06:48 -0500

Seen: 26,124 times

Last updated: Dec 14 '18