I am having trouble debugging when using gdbserver. gdb shows error loading one of the shared libraries.
Error while mapping shared library sections:
`target:<path to library>': not in executable format: Invalid argument
I have no problem when attaching with gdb using PID. But gdbserver throws the above error and then I am unable to set any breakpoints in that shared lib.
Any idea what could be wrong? I have other libraries from the same application that don't seem to have any problem.
I am running on
Centos 6.7
gdb version 7.11.1
gcc version 4.4.7
I encountered this error in GDB 7.11 (the one that ships with Android's NDK-r20), and it was caused by my library being relatively large (300MB), which tripped a bug in gdbserver's integer parser that prevented gdbserver from loading any library larger than 268MB. The bug got fixed in GDB 8.2, by raising the limit to 2GB (https://sourceware.org/bugzilla/show_bug.cgi?id=23198).
I used GDB's sysroot feature to work around this issue: https://sourceware.org/gdb/current/onlinedocs/gdb/Files.html#index-set-sysroot
I copied the libraries from the remote target to my local system* and used set sysroot sysroot-here (where "sysroot-here" is a directory containing the directories/files that I had copied). This forces GDB to read symbols locally instead of from the target.
With this sysroot approach, I did not only work around the bug, but I was also able to use the library with full debugging symbols (about 3GB, which would probably also have tripped newer GDB versions).
* I copied all system libraries and the app's libraries, while preserving the full directory structure / file paths. I wanted to only copy the specific library that triggered the bug, but with sysroot it is all or nothing: Either all libraries are to be found locally on the host, or none. See also: A way to have GDB load libraries from local sysroot and remote gdbserver
I found that gdb version 7.10+ has this problem with my particular binary. Still not sure why. This works fine with 7.9 so I downgraded to overcome this issue.
Related
I installed the flann and libhdf5-serial-dev c++ library on ubuntu. After that, I compiled the flann_example.cpp file without problems. However, when I launched the executable I got the following error message :
Warning! HDF5 library version mismatched error
The HDF5 header files used to compile this application do not match
the version used by the HDF5 library to which this application is linked.
Data corruption or segmentation faults may occur if the application continues.
This can happen when an application was compiled by one version of HDF5 but
linked with a different version of static or shared HDF5 library.
You should recompile the application or check your shared library related
settings such as 'LD_LIBRARY_PATH'.
You can, at your own risk, disable this warning by setting the environment
variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.
Setting it to 2 or higher will suppress the warning messages totally.
Headers are 1.8.16, library is 1.8.7
Bye...
Abandon (core dumped)
I used the following expression to suppress this warning :
cmake -HDF5_DISABLE_VERSION_CHECK=1 -H. -Bbuild
But I still have this message. I looked for the optional flag HDF5_DISABLE_VERSION_CHECK with ccmake to check if it's setting to 1. But I couldn't see this flag.
Someone could help me to solve this issue ?
You can, at your own risk, disable this warning by setting the environment variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.
HDF5_DISABLE_VERSION_CHECK is an environment variable, not a compiler #define or CMake variable. Set it within your shell:
export HDF5_DISABLE_VERSION_CHECK=1
path/to/flann_example
or
HDF5_DISABLE_VERSION_CHECK=1 path/to/flann_example
However, you're probably much better off fixing the root problem (the library mismatch). On Ubuntu, if you always install the Ubuntu-packaged versions of libraries (via apt, aptitude, Synaptic...) instead of installing libraries yourself, this should ensure that all library versions are compatible.
I have an application that is supposed to run on various platforms i.e. ARM, i386, amd64 etc. I want to check any possible memory leaks, I have address sanitizer enabled in GCC as
-fsanitize=address
We are using buildroot to compile the whole OS+Application. To ensure that each developer has same versions of library installed, we pack all the required dynamic libraries in ProjectX/lib
path and set this as LD_LIBRARY_PATH.
All works fine if address sanitizer is switched off. On compiling with address-sanitizer and running the app gives
/lib/i386-linux-gnu/libm.so.6: version `GLIBC_2.23' not found (required by BUILD/host_shared_0_1/host/usr/i686-buildroot-linux-gnu/lib/libasan.so.1)
`GLIBC_2.23' is already there but packed under $ProjectX/lib
However, libasan looks for it under /lib/i386-linux-gnu/ and on finding an incompatible version, throws the error.
QS: How can I instruct libasan to look for the required libraries in the path specified by LD_LIBRARY_PATH only.
It seems that your buildroot and actual runtime environment are binary incompatible i.e. libasan requires libm version newer than the one installed in environment. It's not Asan's problem per se, binary incompatibility may cause issues for the rest of your software as well. For details, google for "version GLIBC_2.23 not found".
How can I instruct libasan to look for the required libraries in the path
specified by LD_LIBRARY_PATH only.
That's what it does now.
I want to use a Qt app on a tiny210 device.
I installed Qt ( qt-everywhere-opensource-src.4.8.5 ) downloaded from here. I managed to compile a simple application for use on tiny210. The problem is that now when I try to run the app on the device, I get the following errors:
libc.so.6: version 'GLIBC_2.15' not found (required by libQtCore.so.4)
libc.so.6: version 'GLIBC_2.15' not found (required by libQtNetwork.so.4)
There is a libc.so.6 in /lib/ on the target device, but it is version 2.11.
I should mention that before getting those errors I also got errors for not having libQtCore.so.4, libQtNetwork.so.4 and libQtGui.so.4. I fixed those errors just by copying the compiled libraries from my host PC to the device.
First question is: Would there have been a better way to provide the needed libraries, or copying them is fine?
Second question is: How can I get over the errors mentioned above?
EDIT : I've read something about building it static, but I am not sure how, and what are the downsides of this.
EDIT2 : I managed to get over the above errors thanks to artless noise's answer, but now I get: error loading shared libraries: libQtGui.so.4: cannot open shared object file: No such file or directory.
The issue is the cross-compiler (apt-get install gcc-arm-linux-gnueabi) is ARM based and this cross compiler has a newer glibc than on the ARM device. You can copy the libc from the cross compiler directory to your ARM device. I suggest testing with LD_LIBRARY_PATH, before updating the main libraries. Use ls /var/lib/dpkg/info/*arm-linux*.list to see most packages related to the ARM compiler. You can use grep to figure out where the libraries are (or fancier things like apt-file, etc).
Crosstool-ng has a populate script, but I dont see it in the Ubuntu packages; it is perfect for your issue. If it is present on your Debian version, I would use it.
The glibc 2.15 is backwards compatible with the glibc 2.11 which is currently on your system. Issues may arise if the compiler was configured with different options (different ABI); however if this is the case, you will have many issues with your built Qt besides the library. In this case, you need to find a better compiler which fits your root filesystem.
So to be clear, on the target
mkdir /lib/staging
cp libc.so-2.15 /lib/staging
cd /lib/staging
ln -s libc.so-2.15 libc.so
LD_LIBRARY_PATH=/lib/staging ls # test the library
You may have to copy additional libraries, such as pthread, resolv, rt, crypt, etc. The files are probably in a directory like sysroot/lib. You can copy the whole directory to the /lib/staging to test it. If the above ls functions, then the compilers should be ABI compatible. If you have a crash or not an executable, then the compiler and rootfs may not be compatible.
Would there have been a better way to provide the needed libraries, or copying them is fine?
Copying may be fine as per above. If it is not fine, then either the compiler or the root filesystem must be updated.
How can I get over the errors mentioned above?
Try the above method. As well, you maybe able to leave your root filesystem alone. Set-up a shadow directory and use chroot to run the Qt application with the copied files as another solution. To test this, make a very simple program and put it along the compiler libraries in a test directory, say /lib/staging as above. Then the test code can be run like,
$ LD_LIBRARY_PATH=/lib/staging ./hello_world
If this doesn't work, your compiler and the ARM file system/OS are not compatible. No library magic will help.
I've read something about building it static, but I am not sure how, and what are the downsides of this.
See Linux static linking is dead. I understand this seems like a solution. However, if the compiler is wrong, this won't help. The calling convention between OS, libraries and what registers are saved by the OS will be implicit in the compiled code. You may have to rebuild Qt with -softfp, etc.
when I compile a c++ program in my computer using g++ and transfer the executable to run it on my university server, I get
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./main)
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./main)
The program runs well on my computer, and I don't have privileges to install any new software on my university servers.
any help ?
Thanks
It seems you are using the standard library as a shared library (default behaviour) when linking your program at home.
So rather than really "linking" the library, your linker just resolves some symbols and does another operation, while delaying the actual loading of the library to run-time.
When you execute your program at your university computer, the loader (the program which actually loads your program in memory and throws the main thread) looks for the libraries your program needs and tries to load them (look for LD_LIBRARY_PATH in linux if you feel curious).
The problem here is that you are linking your program at home with a version of the stdlib that is not the same version as what you have at the university. So when the loader tries to find the library, it fails, and so your program cannot be run.
Solutions:
a) To avoid all these problems use static linking instead of dynamic linking. I am not sure if this is possible with stdlib, but I think it is worth to test it (see: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html and look for "-static" flag)
b) You can try to compile your program at your university computer so it will use the version there.
c) Try to know which stdlib version is installed there and install the same version in your compiler machine.
d) You can try to copy your home version of stdlib to the same folder your application is. This usually works because the loader tends to search for shared libraries in the current application folder before looking in the path set in the environment variable LD_LIBRARY_PATH (linux)
Hope that helps.
P.S.:
Here you have a nice introduction to static vs shared/dynamic libraries http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html
And here (http://en.wikipedia.org/wiki/Library_%28computing%29) a not so nice but more complete library description.
The version of libstdc++.so.6 is too old on the university computer. You have two options:
Statically link with -static. The C++ library will then be merged into the final binary.
Copy the correct version to somewhere in your home directory, then reference it either by passing -rpath /path/to/library/directory at build time, or setting the LD_LIBRARY_PATH environment variable to point to the directory containing the newer libstdc++.so.6.
You can copy your version of the /usr/lib/libstdc++.so.6 to a subdirectory of your home directory of the server, say ~/lib and then run:
$ LD_LIBRARY_PATH=$HOME/lib ./main
Or if you prefer
$ export LD_LIBRARY_PATH=$HOME/lib
$ ./main
And the program should load your private library instead of the system one.
What platforms are you trying to compile for? i.e. 'Your computer' and your 'University servers' ?
You could try compiling your program with the static linking option. This will generate a statically linked executable with all lib dependencies loaded already.
Cheers,
I'm having trouble with gdb and loading debugging information from shared libraries.
The error I get when running from within gdb is:
>>run
Error while mapping shared library sections: libhmmm.so: Success.
....
....
>>break container_main
Error cannot access memory at 0x9f18
The shared library in question exists and is located in the same directory, it contains debugging information and is not stripped.
The application works as expected.
When issuing info sharedlibrary from within gdb all shared libraries are listen but the from and to data is missing for the shared library in question.
Searched but haven't found any solution.
Googling turned up an old bug report and a forum discussion about some similar issue. If you are running GDB version < 6.1 then try upgrading to a newer version.