GDB - step in to statically linked libstdc++ - c++

For reasons beyond the scope of this question I have to statically link the libstdc++ to my executables. The practical downside is that now GDB can't step in to the stdlib symbols. When I was using the shared linked variants of my executable GDB had no issues to show me the accompanying source files (after I had installed the source package through apt-get under ubuntu which installed it under /build)
How can I step into libstdc++ functions when it is statically linked to an executable in GDB, under Ubuntu (14.04)?

Ubuntu package libstdc++6-4.8-dbg provides the static library with debug symbols at /usr/lib/x86_64-linux-gnu/debug/libstdc++.a; try building your executable against it and then run gdb.

Related

How do I build a static C++ openmpi application?

I am trying to do is produce a static MPI executable for Linux machines. The source code is written in C++. When I compile serial versions of the code, with gcc -static, and run ldd on the executable it shows no libraries.
However, when I try this with MPI, there are certain libraries that are not being statically linked. I have built my openmpi on my machine with see below shell commands. I also see that the exact same libraries that are not statically linking with the executable are not statically linking to the openmpi build. At the end of the openmpi build, I get
/home/bevan/Downloads/openmpi-4.0.1/opal/.libs/libopen-pal.a(dl_dlopen_module.o): In function `dlopen_open':
dl_dlopen_module.c:(.text+0x413): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/orte/.libs/libopen-rte.a(plm_rsh_module.o): In function `setup_launch':
plm_rsh_module.c:(.text+0xca2): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/opal/.libs/libopen-pal.a(if.o): In function `opal_ifaddrtoname':
if.c:(.text+0x1e4): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/orte/.libs/libopen-rte.a(ras_slurm_module.o): In function `init':
ras_slurm_module.c:(.text+0x6e4): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/opal/.libs/libopen-pal.a(evutil.o): In function `evutil_unparse_protoname':
/home/bevan/Downloads/openmpi-4.0.1/opal/mca/event/libevent2022/libevent/evutil.c:758: warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
The sort of command chain I feel I should be using is,
tar -xvf openmpi-4.0.1
cd ./openmpi-4.0.1
./configure --prefix="$HOME/.openmpi" --without-memory-manager CXX=g++ CC=gcc LDFLAGS=--static --disable-shared --enable-static
make
sudo make install
export PATH="$PATH:$HOME/.openmpi/bin"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$HOME/.openmpi/lib/"
cd application/directory/build
cmake ..
make application
I would like to be able to run ldd application after compiling with MPI and have no dynamically linked libraries associated with the application.

Using standard C++ library debug symbols? Ubuntu / Linux / libstdc++6-8-dbg?

There is a package called libstdc++6-8-dbg on Ubuntu Linux (latest version at time of writing).
It is described as:
GNU Standard C++ Library v3 (debugging files)
This package contains the shared library of libstdc++ compiled with
debugging symbols.
Among other things it contains these files:
/usr/lib/x86_64-linux-gnu/debug/libstdc++.a
/usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6.0.25
/usr/lib/x86_64-linux-gnu/debug/libstdc++fs.a
Normally to compile a (single translation unit) C++ program with gcc you can write:
$ g++ myprogram.cc
To add generation of debug symbols of user code you pass -g:
$ g++ -g myprogram.cc
But this doesn't include the debug versions of the standard library.
What extra options do you need to pass to g++ to tell it to use the debug versions of the standard library provided by libstdc++6-8-dbg?
The OP wants to resolve C++ standard library's symbols in the backtrace correctly. John's answer correctly states that this could be achieved by linking against the debug version of the standard libraries.
However, Ubuntu also provides debug symbol packages that, once installed, allow GDB to resolve symbols in standard libraries whose debug symbols have been stripped i.e. in the release version of the standard library. We provide a how-to example below (I'm using Ubuntu 20.04):
Suppose the generated binary is named a.out. We first find the version of libstdc++ it links against:
$ ldd a.out
...
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff8dc6f7000)
...
We search for the package that provides the shared library file (/lib is a symbolic link to /usr/lib. The full path must be used here.):
$ dpkg -S /usr/lib/x86_64-linux-gnu/libstdc++.so.6
libstdc++6:amd64: /usr/lib/x86_64-linux-gnu/libstdc++.so.6
Follow the instructions to add the repo for debug symbol packages and then update the package index. The link also describes how one may search for debug symbol packages, but I directly searched with the package name:
$ apt list libstdc++6\*
...
libstdc++6-dbgsym/focal-updates 10.2.0-5ubuntu1~20.04 amd64
...
There will be tons of results, but be sure to look out for dbgsym, rather than dbg! After installing libstdc++6-dbgsym, GDB should be able to resolve the symbols, even if your binary isn't linked against the debug library.
The texts above should answer the OP's question. Now I point out an issue with John's answer.
GDB automatically reads in the debug symbols once you've installed the package. You don't need to compile your program any differently.
This statement is 100% correct, but the figure included is irrelevant and doesn't prove the statement. There are three closely-releated concepts at play here:
Debug library package: The package libstdc++6-8-dbg provides a version of the libstdc++ library with debug symbols.
Debug symbol pagkage: The package libstdc++6-dbgsym provides the debug symbols for the libstdc++ library. That is, it doesn't include any machine instructions for functions like printf, only the debug symbols. libstdc++6-8-dbg bundles code and debug symbols together into one library.
Release library package: The packages libstdc++6-8 and libstdc++6 provide the release versions of the standard library, meaning that they don't carry debug symbols, only the code. Debug symbol packages should be used together with the release libraries.
GDB will automatically read the debug symbols in the debug symbol package, but not in the debug library. The auto-load in John's figure simply states that the Python script /usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6.0.25-gdb.py will be run automatically when the debug library is loaded and has nothing to do with the auto-loading of debug symbols.
GDB automatically reads in the debug symbols once you've installed the package. You don't need to compile your program any differently.
If you want your program to load the debug version your best bet is to adjust the library search path. You could do that by setting LD_LIBRARY_PATH temporarily:
$ LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/debug/
$ ldd test
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007efcef670000)
...
Or permanently:
$ export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/debug/
$ ldd test
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007efcef670000)
...
Or you could make it a system-wide change. You can do that in Ubuntu by adding a config entry to /etc/ld.so.conf.d/ and running ldconfig to update the cache.
$ sudoedit /etc/ld.so.conf.d/debug.conf
$ cat /etc/ld.so.conf.d/debug.conf
/usr/lib/x86_64-linux-gnu/debug
$ sudo ldconfig
$ ldd test
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007f3aced53000)
...
The config files are searched alphabetically so just make sure the one you write (debug.conf above) comes earlier than the default one (x86_64-linux-gnu.conf on my system).

Cross compiling with shared dynamic libraries

In my C++ project, I'm compiling and linking against a library that makes use of OpenSSL.
I need to compile this project for my BeagleBone which has openssl installed by default. I have downloaded libssl-dev on my development machine.
Thus, I can compile the project fine if I'm compiling for my development machine on x86_64, but I am not able to successfully cross compile:
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto
This indicates I need to have armhf binaries for OpenSSL, which seems a bit of a waste really since I have them on my BeagleBone if it can just be patient and wait until I deploy it.
Is the only way around this cross-compiling OpenSSL myself? Where would I then need to install the .so files (I guess make install would be a bad idea?)
This indicates I need to have armhf binaries for OpenSSL
Correct.
which seems a bit of a waste really since I have them on my BeagleBone if it can just be patient and wait until I deploy it.
You appear to think that shared libraries are only needed at runtime, but that is not the case.
ELF stands for executable and linking format. The .so is very much needed at static link time to construct various tables in the main executable, which will then be used by the loader at runtime to resolve references from the main executable to the .so.
If you are familiar with Win32, you can think of .so as a combination of Win32 .LIB and .DLL packed into a single file.

Static linked GDB cannot use HostName in target remote

The GDB is built on RHEL-4.7. I run the GDB on RHEL-6.3. If the GDB is dynamically linked, everything works OK. If the GDB is statically linked, I got
(gdb) target remote :2107
localhost: unknown host
:2107: No such file or directory.
When GDB is built statically, we got a warning message:
warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
I also searched with google, it seems that gethostbyname depends on the glibc library. I tried to install the compatible glibc library on RHEL-6.3. But there's no luck. Any hint?

distribute gcc 4.7 program with shared libraries on OS X

I've compiled a command-line tool against some C++ dynamic libraries using GCC 4.7 on Mac OS X 10.8. On the development system, the compiler was installed by MacPorts into /opt/local and the libraries reside in /usr/local/lib. The dynamic libraries are compiled from source alongside the program. (But they're built by cmake and I don't want to mess with that system.)
When I try to run it on another machine by putting the necessary dylibs into the executable's directory and DYLD_LIBRARY_PATH, it complains about an undefined symbol in the C++ standard library. It appears to be trying to load the older, builtin GNU standard library from /usr/lib/libstdc++.6.dylib.
How can I force the system to load the desired libstdc++?