C++ Shared library gives floating point exception when linked with C application - c++

Background:
A C++ library for etcd client having APIs to communicate with etcd server, to use this library in C application, we wrote C++ wrappers over this library so that it can be called by C application.
Created a shared library using the below command:
g++-7 -ggdb -fPIC -shared -o libetcd_c++.so etcd_client_wrapper.cc etcd_client_txn_wrapper.cc etcd_client.cc etcd_client_txn.cc utils/string.cc pb/*.cc -std=c++1z -I ./pb/etcd -rdynamic -Wl,-call_shared -lglog -lprotobuf -lgrpc++ -lgrpc -Wl,-call_shared -lpthread -ldl -lc
placed this library to default library path /usr/local/lib and load the library with sudo ldconfig.
Now using this etcd_c++ library APIs, wrote a C code to insert simple key-value to etcd keyspace. Compiled using below command:
gcc -ggdb -o cwrap sample_wrapper.c -rdynamic -pthread -static-libstdc++ -Wl,-non_shared -lglog -lprotobuf -pthread -lz -lgrpc++ -lprotobuf -lgrpc -lz -lcares -lssl -lcrypto -lunwind -llzma -lgflags -Wl,-call_shared -lpthread -ldl -letcd_c++ -lstdc++
The compilation goes fine. But while executing the resulted binary, it gives floating point exception in grpc++ library.
Questions:
What floating point exception has to do with the library?
We thought it might be an issue with C to C++ transition, but when converted the same C code to C++ with same wrapper API. Gives the floating point exception.Now If we replace the wrapper API with direct grpc++ library API, in the C++ code, it works fine. Is it a linking issue?
Compiling a C++ application:
g++-7 -ggdb -o wrap example.cc -std=c++1z -rdynamic -pthread -static-libstdc++ -Wl,-non_shared -lglog -lprotobuf -pthread -lz -lgrpc++ -lprotobuf -lgrpc -lz -lcares -lssl -lcrypto -lunwind -llzma -lgflags -Wl,-call_shared -lpthread -ldl -letcd_c++
EDIT: Some findings, https://bugs.launchpad.net/ubuntu/+source/grpc/+bug/1797000
Though We are not using -Wl,-Bsymbolic-functions option, but the issue is somewhat similar to above.

Related

Why would I need to list -ldl before a library that calls dlopen/dlclose/dlerror when linking

I am building an executable (foo.exe let's call it) on RHEL with gcc 6.2. It links against a few third-party libraries, libzzdesign.so, libyydesign.so. Yydesign uses dlopen/dlclose/dlerror. I would expect this command-line to work:
g++ -Wall -fcheck-new -fno-strict-aliasing -msse2 -fno-omit-frame-pointer -pthread -O3 -Wl,--export-dynamic -o foo.exe foo.o -L/path/to/zzdesign -Wl,-rpath=/path/to/zzdesign -lzzdesign -L/path/to/yydesign -Wl,-rpath=/path/to/yydesign -lyydesign -ldl
(I'm listing all the options used in case it matters)
It produces the errors,
/path/to/yydesign/libyydesign.so: undefined reference to 'dlclose'
/path/to/yydesign/libyydesign.so: undefined reference to 'dlerror'
If I change the command line to put -ldl before -lyydesign:
g++ -Wall -fcheck-new -fno-strict-aliasing -msse2 -fno-omit-frame-pointer -pthread -O3 -Wl,--export-dynamic -o foo.exe foo.o -L/path/to/zzdesign -Wl,-rpath=/path/to/zzdesign -lzzdesign -L/path/to/yydesign -Wl,-rpath=/path/to/yydesign -ldl -lyydesign
... it works without error.
This is the opposite of everything I thought I knew about order of libraries on the command line when linking.
Why does -ldl have to come before -lyydesign?
Other than dumb luck to stumble across this solution, how could I troubleshoot the original error to understand what's going on?
And since changing the build system to move -ldl first in all the places it's needed is kind of a pain, is there a way I can avoid having to put -ldl first?
Order of libs for LD does matter. Lib yydesign use dlclose and dlerror that's why lib dl need to be passed before yydesign.

Failure to link v8 in a native Dart extension

I am trying to use v8 in a Dart native extension.
The v8 getting started guide says to compile the hello world example like this.
g++ -I. -Iinclude samples/hello-world.cc -o hello-world -Wl,--start-group \
out.gn/x64.release/obj/{libv8_{base,libbase,external_snapshot,libplatform,libsampler},\
third_party/icu/libicu{uc,i18n},src/inspector/libinspector}.a \
-Wl,--end-group -lrt -ldl -pthread -std=c++0x
Dart says to compile native extensions like so:
g++ -fPIC -I{path to SDK include directory} -DDART_SHARED_LIB -c sample_extension.cc
gcc -shared -m32 -Wl,-soname,libsample_extension.so -o libsample_extension.so sample_extension.o
This is the hybrid I came up with
g++ -fPIC -I{path to SDK include directory} -Iinclude -DDART_SHARED_LIB -c sample_extension.cc -std=c++0x
gcc -shared -Wl,-soname,libsample_extension.so -Wl,--start-group out.gn/x64.release/obj/{libv8_{base,libbase,external_snapshot,libplatform,libsampler},third_party/icu/libicu{uc,i18n},src/inspector/libinspector}.a -Wl,--end-group -o libsample_extension.so sample_extension.o -lrt -ldl -pthread -std=c++0x
However, while trying to run my application, I get an error stating that v8 is not linked properly.
dart: symbol lookup error: /mnt/c/Users/zvacu/Documents/Code/Dart/require/libsample_extension.so: undefined symbol: _ZN2v82V828InitializeICUDefaultLocationEPKcS2_
I can manage to link it properly when using the hello world example provided.
Doing a little research it seems like the problem it is on the -shared property on the second command. You need to pay attention with C++ and shared libraries, so check if your library get's all its dependencies by:
ldd /mnt/c/Users/zvacu/Documents/Code/Dart/require/libsample_extension.so
After this you will get a list of all dependencies, then you will need to search if there is anyone missing.
If this does not answer your question, see this related answer:
Undefined symbol when loading a shared library

Linker error: Multiple definitions of 'ff_log2_tab'

I am trying to build a shared library that links a static version of libav into it. I build the library with --enable-pic to make sure its usable for me. But upon linking with the following command:
g++ -shared -o libbrake.so -L./ -L./libs -Wl,-z,defs -Wl,--whole-archive -Wl,-Bsymbolic -lavcodec -lavfilter -lavformat -lavresample -lavutil -lswscale -lbluray -ldvdnav -ldvdread -lhandbrake -lvpx -ldl -lm -lpthread -lx264 -ltheoraenc -lvorbis -ljansson -la52 -lass -lbz2 -lz -lxml2 -lopus -lmp3lame -logg -lsamplerate -lfontconfig -ldca -lharfbuzz
The needed static libs of libav are in the ./libs directory as .a archives.
Upon linking I get the error:
./libs/libavformat.a(log2_tab.o):(.rodata+0x0): multiple definition of `ff_log2_tab'
Is there any way to resolve this?
Ive done it now this way: with ar d i delete the multiple object file. but i think this is pretty "dirty"
– Nidhoegger

C++ Symbol lookup error in shared library when accessing boost bind

I am trying to add multithreading into my library, so I am working on creating a thread executor for my library. For this I am using boost threads.
This is the error I am getting when running a test case that links to the library:
symbol lookup error: libmylibexample.so.0: undefined symbol: _ZTVN5boost6detail16thread_data_baseE
This is the line of code in my shared library that is causing the error:
MyNameSpace::Producer producer = MyNameSpace::Producer();
threads.create_thread(boost::bind(&MyNameSpace::Producer::run, &producer));
I am compiling the library using autotools and libtool. The code compiles fine. I then create a test case that I am trying to reference the library. Here is the compilation order for compiling the test case:
g++ -I. -I../include -g -O2 -MT runTest-runTest.o -MD -MP -MF .deps/runTest-runTest.Tpo -c -o runTest-runTest.o `test -f 'runTest.cc' || echo './'`runTest.cc
and this is my linking stage:
mv -f .deps/runTest-runTest.Tpo .deps/runTest-runTest.Po
/bin/bash ../libtool --tag=CXX --mode=link g++ -g -O2 ../libmylibexample/libmylibexample.la -o runTest runTest-runTest.o -lboost_system -lboost_filesystem -lboost_regex -lboost_thread-mt -lfftw3 -ltiff
libtool: link: g++ -g -O2 -o .libs/runTest runTest-runTest.o ../libmylibexample/.libs/libmylibexample.so -lboost_system -lboost_filesystem -lboost_regex -lboost_thread-mt -lfftw3 /usr/lib/x86_64-linux-gnu/libtiff.so
One of my colleagues suggested initializing some boost templates relating to threading to help the shared library to load the symbol from the boost_thread library. I am not entirely certain the best method to do this and if this it the right way of making things get loaded.
So to wrap things up: The error appears to involve not being able to load a symbol defined in libboost_thread from my shared library.
As the error indicates, you need to link libmylibexample with libboost_thread.

Resolving undefined references with MySQL C++ Connector

I'm trying to compile this (also listed in the mysql c++ connector documentation): http://pastebin.com/HLv4zR0r
But I get these errors: http://pastebin.com/3t0UbeFy
This is how I tried compiling:
g++ -o test test.cpp `mysql_config --cflags --libs` -I./include/cppconn -L./lib -lmysqlcppconn-static
The result of running mysql_config --cflags --libs is:
-I/usr/include/mysql -DBIG_JOINS=1 -fno-strict-aliasing -g
-L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -lrt -ldl
Edit:
After running Jonathan Wakely's suggested command with properly-ordered linker arguments,
g++ -o test test.cpp -I./include/cppconn -L./lib -lmysqlcppconn-static `mysql_config --cflags --libs`
I get different errors: http://pastebin.com/4EWNgy9i
The mysqlcppcon library depends on the mysqlclient C libraries, so you need to put the mysqlclient libs after -lmysqlcppconn-static
g++ -o test test.cpp -I./include/cppconn -L./lib -lmysqlcppconn-static `mysql_config --cflags --libs`
The order of linker arguments matters. The linker looks at each file in order and decides if it needs any symbols from it. By the time it sees the libmysqlcppconn-static.a file it has already looked at (and ignored) the libmysqlclient.so library, and doesn't go back to look at it again.