Shared Library undefined symbol - c

Similar title question exist but not the same problem .
I have two machines one with CentOS 7.3.1611 and one with similar to CentOS you can say custom RedHat .
i have a SDK that i need to run on the custom machine but it doesn't have yum gcc.
so i had to compile and install the SDK on CentOS, after that i copied the result to the custom machine (shared libraries, scripts , binaries ...) in Order to run them there .
Naturally the SDK worked fine on CentOS, but on the custom machine while loading some of the drivers and other libraries fine , i got an error when loading a specific library as follow :
dlopen (libsdkpolicerlib.so) failed: (/usr/local/bin/../lib/libsdkpolicer.so.1: undefined symbol: policer_validate_packet_type)
Notice there are three shared objects involved here :
libsdkpolicerlib.so the one that dlopen tries to open
libsdkpolicer.so.1
libpolicercomlib.so that contains the symbol policer_validate_packet_type
all of the shared object are in the same directory /usr/local/lib .
libpolicercomlib.so actually contains the symbol .
I have :
verified the ld.so.cache contains all of the above libraries .
Also i have added /usr/local/lib to the LD_LIBRARY_PATH variable .
Executed ldconfig with "-n" with the path ...
I know this isn't the best way to do this sort of stuff, but this solution is temporary .
My question is what else do i have to verify in order for this to work ?
What am i missing here ?

You can check /lib/libsdkpolicer.so.1 with ldd command, maybe the libpolicercomlib.so file which you copy just is a link file, and check it on your machine without yum GCC. If everything is correct, you can copy the /lib64/ld-linux-x86-64.so.2 loader from your complie machine to your new machine(backup it before) and try it.

Related

Does a .so library need to be present at run time in all cases

My question is in relation to .so shared libraries. I am building a project that uses cmake on one ubuntu machine but running the application on another ubuntu machine.
In the CMakeLists.txt file, I have the following lines:
project (clientapp)
add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})
LINK_DIRECTORIES(/home/user//mraa-master-built/build/src)
target_link_libraries (clientapp libmraa.so)
target_link_libraries(clientapp m)
These lines add two libraries libmraa.so and the math library to the executable and it runs successfully on the other machine.
My understanding of shared libraries is that they must be present at compile time, and when the application starts. But I do not have the libmraa.so file on the other machine and the application runs ok. I expected it not to work.
Is my assumption correct?
In general, gcc and clang support lazy linking/binding of symbols, but not for entire libraries. This means that all of the shared objects (ie: .so files) should be present at application startup, at a minimum. The one exception to this is if you modified your makefile to not link against these libraries, and you manually call library functions via dlopen()/dlsym(), etc.
The binding of individual symbols within those libraries can be postponed until they are needed, or you can force all the symbols to be resolved at startup, using -z lazy or -z now, respectively.
It is strange that your application runs without libmraa.so being present. The two most likely reasons your application is running in the absence of the library is:
Your application isn't using any symbols defined in the library, so the linker ignores the library at build time (try ldd app_name and see if your library is present in the list of libraries provided by ldd).
Something is amiss in your build script, and you are statically linking against a .a archive of the library.
Edit: In response to how the application knows how to find the library, your linker (ld in this case) will use rpath lookup to decide which directories to use in its search for the appropriate library. You can see how this works by doing something like LD_DEBUG=libs app_name from the command line. You can also add an extra path via LD_LIBRARY_PATH=/some/path app_name.
Is my assumption correct?
Yes.
There are two likely explanations for why the application runs anyway:
You are mistaken, and there is libmraa.so somewhere on the machine (though perhaps not in the place where you looked), or
Your compiler defaults to -Wl,--as-needed by default, and your binary does not in fact depend on libmraa.so despite the fact that it appears on your link line.
You can trivially confirm or disprove either of the above guesses.
To confirm guess 2, do this:
readelf -d clientapp | grep NEED | grep libmraa
# if there is no output, guess 2 is correct
If guess 2 is wrong, to confirm guess 1, do this (on machine without libmrra.so):
ldd clientapp | grep libmraa.so
# if guess 2 is incorrect, and this command produces no output, then
# your dynamic loader is broken, which is very unlikely.

Missing libgcc_s_dw2-1.dll

I have a Windows 7 64bit system with the latest MinGW (32bit) installed along with the Qt 5.5 SDK (again 32bit) which also ships with its own MinGW. Due to the fact that I'm not the only one using the system I can't remove the standalone MinGW.
My project is using qmake and is a plain C project (not C++). Everything builds fine but when I try to execute my binary in the command line I get that the application was unable to start due to a missing libgcc_s_dw2-1.dll on the system.
After looking into the issue I found that both the standalone MinGW and the one shipped alongside the Qt SDK have the mentioned DLL.
Standalone MinGW - libgcc_s_dw2-1.dll is located inside the bin subdirectory of the MinGW installation where the binaries are located (gcc, g++, gdb etc.)
Qt MinGW - libgcc_s_dw2-1.dll is located inside C:\Qt\Tools\mingw492_32\i686-w64-mingw32\lib subdirectory while the MinGW components' binaries are inside C:\Qt\Tools\mingw492_32\i686-w64-mingw32\bin.
I would like to know how to properly set my PATH variable so that:
The application starts properly
No conflicts with the standalone MinGW installation occur
Just a side-note: I've already checked other posts here on SO but was unable to find a solution (perhaps I've missed it). I have also tried LIBS += -static but the result is the same.
You just need to copy this dll with your executable, i.e.:
cp <path-to-qt-install-dir>\qt5.7.0\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll <path-to-dest-dir>
You mat find that you have other dependencies, to see which other deps you have you can use: ldd <your-executable>. You only need to copy the qt specific dlls you can see these by:
ldd <executable> | grep -i qt
note
You can statically link it with:
linker commands like -static-libgcc or -static, but I think you start to hit LGPL issues and also you may need to statically compile qt from source - can't recall for this particular file.
note2
Sorry ldd is for linux, just realized you have windows, in which case you can use one or both of:
dependency walker: from here
<path-to-qt-bin-folder>\windeployqt.exe <path-to-your-executable>
I have mixed results with windeployqt, but if you have any plugins its quiet good for getting that part sorted.

Sleuthkit -- Error while loading shared libraries

After successfully building and compiling sleuthkit library [4.2 version], I tried to write an introspection tool using the library.. Thing is whenever i am trying to compile the program in order to test it and I am using a function from the library API I'm get the following error :
error while loading shared libraries: libtsk.so.13: cannot open shared object file: No such file or directory
I found thought that this file exists in /usr/local/lib folder . Am i missing something ? ./configure && make didn't give me any errors.. and I am including -ltsk on the makefile!
My pc information : XEN hypervisor [Ubuntu 12.04 x64bit] and i am trying to investigate a guest vm running ubuntu 12.04 x32bit
Thanks in advance
I found a solution to the problem , if I install -dev package...
sudo apt-get install libtsk-dev
Also read this useful article... Understood why exactly that happened .

UNIX: Cannot find file or directory after cross-compiling a binary that uses shared object files

I am able to successfully cross-compile a binary file that can run on an ARM system such as Rasberry Pi. Without linking to a third-party library, normal C++ code runs on the device successfully (I.E. cout << "Hello World!" << endl;).
The issue I'm running into is that when I run the executable after it's been linked against a third-party library, I get the standard UNIX error "No such file or directory." when the binary tries to access the shared object file. I have the file it's looking for copied into the usr/lib folder, the usr/local/lib folder, and the folder where the executable is sitting itself.
Also, I went and added a good value to LD_LIBRARY_PATH so the runtime linker can search at these locations. My guess is that the "system" maybe hiding these files from the executable?
And to add more information, I ran the readelf command on the binary and the shared object file and it gives me the proper descriptions of the file. It tells me that the binary file is a 32-bit file and requires this shared object library file that I mentioned it cannot find. Even during link time in the build phase, I add the following linker command -Wl,-rpath, to set the location of where to look for the shared object file. Please note I'm compiling on a Macintosh Machine, and not on the Rasberry Pi itself. Hence cross-compiling.
I have a feeling it's a setting, because the object file is visible/valid in multiple locations. If anyone has experienced this before, please any advice is appreciated. Thanks in advance.
I actually figured out the problem recently.
The problem was that I was using Eclipse. The third party library files I was using were named in the format "libSHAREDFILENAME.so". Eclipse doesn't like that very much when setting up which libraries to use in the IDE. It expects you to strip off the "lib" and the ".so" portion from the file name. So a file named "libSHAREDOBJECT.so" should be referenced as "SHAREDOBJECT" in Eclipse. It doesn't like the "lib" prefix or the ".so" suffix.

How to manage libstdc++.so.6: wrong ELF class: ELFCLASS64 at computer cluster

I have a problem with the libstdc++.so.6 library when I execute a program in MATLAB. The code works fine on my laptop and my desktop, which is why I'm sure the problem is a library or linking compatibility issue:
/home/arturo/Virality/viral_cluster_ml/Viral_features/code/segment_pedro/segment: error while loading shared libraries: libstdc++.so.6: wrong ELF class: ELFCLASS64
I've google some answers on how to fix the library, and some say that I should remove the library to later re-install the correct version:
error while loading shared libraries: libstdc++.so.6: wrong ELF class: ELFCLASS64
The problem is that I can't afford the luxury to delete a library, because I am ssh'ing to a cluster at the lab I'm working in. I really wouldn't want to mess up any programs that are running at the cluster, so isn't there another way of fixing this problem? I'm hoping a solution similar to:
sudo apt-get install libstd++6
that doesn't require me to delete or modify any files, but rather to install them.
Or maybe the error is that I'm not linking the library correctly?
The file does exist, as when I use
locate libstd++.so.6
the computer finds it at these directories:
/usr/lib64/libstdc++.so.6
/usr/lib64/libstdc++.so.6.0.13
/usr/local/MATLAB/R2012b/sys/os/glnxa64/libstdc++.so.6
/usr/local/MATLAB/R2012b/sys/os/glnxa64/libstdc++.so.6.0.13
/usr/local/MATLAB/R2012b/toolbox/sldv/sldv/polyspace-dvo/lib/x86-linux/libstdc++.so.6
/usr/local/MATLAB/R2012b/toolbox/sldv/sldv/polyspace-dvo/lib/x86-linux/libstdc++.so.6.0.13
/usr/local/MATLAB/R2013a/sys/os/glnxa64/libstdc++.so.6
/usr/local/MATLAB/R2013a/sys/os/glnxa64/libstdc++.so.6.0.13
/usr/local/MATLAB/R2013a_DCS/sys/os/glnxa64/libstdc++.so.6
/usr/local/MATLAB/R2013a_DCS/sys/os/glnxa64/libstdc++.so.6.0.13
/usr/local/Matlab_R2012a/bin/glnxa64/libstdc++.so.6
/usr/local/Matlab_R2012a/bin/glnxa64/libstdc++.so.6.0.13
/usr/local/Matlab_R2012a/sys/os/glnxa64/libstdc++.so.6
/usr/local/Matlab_R2012a/sys/os/glnxa64/libstdc++.so.6.0.13
/usr/local/Matlab_R2012a/toolbox/sldv/sldv/polyspace-dvo/lib/x86-linux/libstdc++.so.6
/usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.13-gdb.py
/usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.13-gdb.pyc
/usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.13-gdb.pyo
/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.13-gdb.py
/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.13-gdb.pyc
/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.13-gdb.pyo
I've also tried setting the path to the the file before running MATLAB, without anyluck:
LD_LIBRARY_PATH=/usr/lib64:/home/arturo/Virality/viral_cluster_ml/Viral_features/code/scene_sun ./matlab
Similar link and problem:
http://www.linuxquestions.org/questions/linux-newbie-8/apt-get-messed-up-812346/
Problem was solved by recompiling a subfolder of the code on the cluster.

Resources