Bindings of jq to nodejs undefined symbol - c++

I have a problem regarding binding jq library using node-gyp.
I have 2 node-gyp files
for building the nan code
for building the JQ code
You can see the full repo in here https://github.com/danielsinai/jq-node-bindings.git
I'm getting the error while trying to run the following program (index.js):
const jq = require('bindings')('jq-node-bindings');
console.log(jq)
const x = jq.exec(JSON.stringify({ foo: 'bar' }), '.foo');
console.log(x)
The error:
node: symbol lookup error: /root/code/jq-bindings/build/Release/jq-node-bindings.node: undefined symbol: _Z7jq_init
nm command output
nm -g build/deps/libjq.so.1 | grep jq_init
000000000003acb0 T jq_init
ldd command output
ldd /root/code/jq-bindings/build/Release/jq-node-bindings.node
linux-vdso.so.1 (0x00007ffe0bbf0000)
libjq.so.1 => /root/code/jq-bindings/build/Release/../deps/libjq.so.1 (0x00007feb84541000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007feb84316000)
libm.so.6 => /lib64/libm.so.6 (0x00007feb8423b000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007feb84220000)
libc.so.6 => /lib64/libc.so.6 (0x00007feb84017000)
/lib64/ld-linux-x86-64.so.2 (0x00007feb84630000)

Solved, missing the extern keyword as I was running cpp code against c module hope it will help someone in the futrue
extern "C" {
#include "jq.h"
#include "jv.h"
}

Related

How to use dynamic linking to implement missing symbol in shared library with additional shared library

I have a shared library in linux that was compiled using glibc and I want to run it in Alpine linux without recompiling it against Alpaine C libraries.
I found that there is solution to install gcompat - which is wrapper to Alpine C library to glibc and than with
patchelf --add-needed libgcompat.so.0 /var/lib/libdyn_MyLib.so
I can add the gcompat library into the my own library without compilation and it will tell the dynamic loader to look for symbols also in libgcompat.so
It worked partially and the ldd output of the shared library is:
ldd /var/lib/libdyn_MyLib.so
/lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
libgcompat.so.0 => /lib/libgcompat.so.0 (0x7f78ff278000)
libicudata.so.50 => /lib/libicudata.so.50 (0x7f78fdca4000)
libicui18n.so.50 => /lib/libicui18n.so.50 (0x7f78fd8a6000)
libicuuc.so.50 => /lib/libicuuc.so.50 (0x7f78fd52d000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f78fd2df000)
libm.so.6 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
libgomp.so.1 => /usr/lib/libgomp.so.1 (0x7f78fd298000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f78fd27a000)
libpthread.so.0 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
libc.so.6 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
ld-linux-x86-64.so.2 => /lib/ld-linux-x86-64.so.2 (0x7f78fd274000)
libucontext.so.1 => /lib/libucontext.so.1 (0x7f78fd26f000)
libobstack.so.1 => /usr/lib/libobstack.so.1 (0x7f78fd26a000)
libdl.so.2 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
Error relocating libdyn_MyLib.so: feenableexcept: symbol not found
I can see that libgcompat.so is listed and there are no "not found" libraries.
All the "symbol not found" disappeared except for "feenableexecpt".
After referring to documentation, feenableexecpt is extension of glibc and not supported in gcompat package and I can understand why it's hard to support it.
I want to ignore this function call so I tried to implement "feenableexecpt" that does nothing and add this library to libdyn_MyLib.so (like implementing my own feenableexecpt that does nothing as they implement glibc library using different library).
Here is my code:
glibc_extension.h:
#ifndef __ALPINE_GLIBC__
#define __ALPINE_GLIBC__
extern int feenableexcept(int __excepts) throw ();
#endif
lib_ext.cpp:
#include "glibc_extension.h"
int feenableexcept(int e) throw () {
return 0;
}
complied it as share library:
gcc -Wall -Werror -shared -o libalpine.so lib_ext.cpp
I can see feenableexecpt in the symbols table using nm.
I had also used patchelf to add this library to my shared library, here is the output of the shared library again:
ldd /var/lib/libdyn_MyLib.so
/lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
libalpine.so => /lib/libalpine.so (0x7f78ff28b000)
libgcompat.so.0 => /lib/libgcompat.so.0 (0x7f78ff278000)
libicudata.so.50 => /lib/libicudata.so.50 (0x7f78fdca4000)
libicui18n.so.50 => /lib/libicui18n.so.50 (0x7f78fd8a6000)
libicuuc.so.50 => /lib/libicuuc.so.50 (0x7f78fd52d000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f78fd2df000)
libm.so.6 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
libgomp.so.1 => /usr/lib/libgomp.so.1 (0x7f78fd298000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f78fd27a000)
libpthread.so.0 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
libc.so.6 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
ld-linux-x86-64.so.2 => /lib/ld-linux-x86-64.so.2 (0x7f78fd274000)
libucontext.so.1 => /lib/libucontext.so.1 (0x7f78fd26f000)
libobstack.so.1 => /usr/lib/libobstack.so.1 (0x7f78fd26a000)
libdl.so.2 => /lib/ld-musl-x86_64.so.1 (0x7f79007cc000)
Error relocating libdyn_MyLib.so: feenableexcept: symbol not found
I can see libalpaine.so in the ldd output but still "feenableexecpt" is missing.
What have I done wrong?
Thanks
I was expecting the feenableexecpt symbol to be found by the dynamic program executer.

How to solve "symbol lookup error" when running a program and nm and ldd show correct linkage?

I'm running into a symbol lookup error whenever I run a specific version/configuration of the simulator Gem5, using commit c5ca3ef6b9ff967722b07bc160fa9068e0d9e39c.
The building is done by a SConscript (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)), and after running the program
./build/X86/gem5.opt ./configs/example/se.py -<test program> <configs>
the following error is generated:
symbol lookup error: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: undefined symbol: _ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv, version GLIBCXX_3.4
Checking nm's output, I notice the symbol is there
nm -D /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep _ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv
000000000008e4d0 T _ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv
Then, as suggested by another answer, I check ldd:
ldd build/X86/gem5.opt
linux-vdso.so.1 => (0x00007fff8b5d9000)
libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007fe4b4534000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe4b4317000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fe4b40fd000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fe4b3ef5000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe4b3b73000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe4b386a000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe4b3654000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe4b328a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe4b3086000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fe4b2e83000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe4b4ac2000)
And as can be seen, libstdc++ is being chosen correctly. Would anyone have a suggestion to fix this linking problem?

Building library on Ubuntu, using it in a project on Arch - doesn't build

I'm building a dynamic library on Ubuntu 14.04.5, that depends on some static libraries (Boost and OpenSSL).
If I use this library in a project on another Ubuntu machine, it works perfectly. However, if I build it and use it in a project on an Arch machine (Antergos), it says the following during the build process:
main.cpp.o: In function `init()':
main.cpp:(.text+0xf8): undefined reference to `Util::generateString[abi:cxx11](int)'
I'm building my project with the following:
g++ -Ldeps -Ideps/include main.cpp -lmylib
deps contains libmylib.so and the required header files in deps/include.
If I run ldd on my mylib.so on Ubuntu, I get the following:
linux-vdso.so.1 => (0x00007ffdd24cf000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f10b2f97000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f10b2c91000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f10b2a73000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f10b26ab000)
/lib64/ld-linux-x86-64.so.2 (0x00007f10b3ff3000)
If I run ldd on mylib.so on Antergos, I get the following:
linux-vdso.so.1 (0x00007ffcce115000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f5a42fef000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f5a42cdc000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f5a42abe000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f5a4271a000)
/usr/lib64/ld-linux-x86-64.so.2 (0x000055ced49a7000)
I'm probably missing something easy, but I can't seem to get it to work. What am I doing wrong?
I'm assuming that Util::generateString[abi:cxx11](int) is a function exported by your libmylib.so library? If so, you may want to recompile that library first and then reattempt the compilation/linking of main.cpp.
I suggest this to ensure that the c++ standard library that each component is linked against is the same version. It looks like libmylib.so was compiled against the c++11 standard library, you'll want to ensure main.cpp matches that. You can always specify which one you're linking against using --std= option (e.g. --std=c++11, --std=c++0x, --std=c++17).

How to configure shared library search path after building GCC on my own?

I just built GCC 5.1 on Ubuntu 14.04, which has gcc 4.8 as default. When I try to build things with it, I find that ld will use the default libstdc++ instead of the newly build one.
Here is the output:
drizzlex#dx ~/test
$ g++ hello.cpp
drizzlex#dx ~/test
$ ldd a.out
linux-vdso.so.1 => (0x00007ffde0d25000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa181ad2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa1817cc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa1815b5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa1811f0000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa181dfd000)
And if I use $ export LD_LIBRARY_PATH=/usr/local/lib64/, it will find the right one.
drizzlex#dx ~/test
$ ldd a.out
linux-vdso.so.1 => (0x00007fffeeaf5000)
libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00007f4583d92000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4583a67000)
libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00007f4583850000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f458348b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f458410e000)
I would like to know what should I do to make it correct? Since I know set LD_LIBRARY_PATH is not the best choice.
For building with g++ 5.1 use this:
$ g++5.1 hello.cpp -Wl,-rpath,/usr/local/lib64
And you will not need set LD_LIBRARY_PATH.
This is from https://en.wikipedia.org/wiki/Rpath
rpath is a term in programming which refers to a run-time search path
hard-coded in an executable file or library, used during dynamic
linking to find the libraries the executable or library requires.

Asterisk module app_transcoder failed for libavcodec.so (undefined symbol avacodec_init)

I am trying to integrate the 3G video gateway with Asterisk(1.4.0).
When i load the module "app_transcoder.so" (which does the actual video transcoding), then
asterisk hangs and with "asterisk -vvvvvc" i got
asterisk: symbol lookup error: /usr/lib/asterisk/modules/app_transcoder.so: undefined symbol: avcodec_init
Showing the dependencies of app_transcoder.so by "ldd /usr/lib/asterisk/modules/app_transcoder.so" gives:
linux-vdso.so.1 => (0x00007fff851ff000)
libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0x00007f8604ec3000)
libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x00007f8604c6e000)
libc.so.6 => /lib64/libc.so.6 (0x00007f86048d9000)
libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x00007f86046a7000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f860448a000)
libx264.so.142 => /usr/local/lib/libx264.so.142 (0x00007f86040d1000)
libgsm.so.1 => /usr/lib/libgsm.so.1 (0x00007f8603ec6000)
libm.so.6 => /lib64/libm.so.6 (0x00007f8603c42000)
libz.so.1 => /lib64/libz.so.1 (0x00007f8603a2b000)
/lib64/ld-linux-x86-64.so.2 (0x0000003b14200000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f8603827000)
"avcodec_init" comes from libavcodec.so file but it has no symbols as from the commands:
nm -a /usr/local/lib/libavcodec.so.54
gives:
nm: /usr/local/lib/libavcodec.so.54: no symbols
i am following the instructions from Medooze
CentOS-6.4
ffmpeg-1.2.6
asterisk-1.4.0
x264- 0.142x
ptlib-2.6.7
mpeg4ip-1.6.1
Any advice is appreciated.
add /usr/local/lib to your library path /etc/ld.so.conf
after that, execute "ldconfig"
recompile asterisk.
Found this ffmpeg mailing list: avcodec_init() isn't used nowadays. Instead avcodec_register_all() is used. It seems you may need to downgrade ffmpeg.