How to Find What Version of Libstdc++ Library Is Installed on Your Linux MAChine

Reading libstdc++ version at runtime

Here is a linux program that simply lists the absolute real paths of the DSOs it has
loaded (as enumerated by dl_iterate_phdr) that are accessible files.
(All linux programs load linux-vdso.so, which isn't actually a file).

main.cpp

#include <link.h>
#include <climits>
#include <cstdlib>
#include <string>
#include <vector>
#include <iostream>

int
get_next_SO_path(dl_phdr_info *info, size_t, void *p_SO_list)
{
auto & SO_list =
*static_cast<std::vector<std::string> *>(p_SO_list);
auto p_SO_path = realpath(info->dlpi_name,NULL);
if (p_SO_path) {
SO_list.emplace_back(p_SO_path);
free(p_SO_path);
}
return 0;
}

std::vector<std::string>
get_SO_realpaths()
{
std::vector<std::string> SO_paths;
dl_iterate_phdr(get_next_SO_path, &SO_paths);
return SO_paths;
}


int main()
{
auto SO_paths = get_SO_realpaths();
for (auto const & SO_path : SO_paths) {
std::cout << SO_path << std::endl;
}
return 0;
}

Which for me runs like:

$ g++ -Wall -Wextra main.cpp && ./a.out
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
/lib/x86_64-linux-gnu/libgcc_s.so.1
/lib/x86_64-linux-gnu/libc-2.27.so
/lib/x86_64-linux-gnu/libm-2.27.so
/lib/x86_64-linux-gnu/ld-2.27.so

Live demo

As you see, the full version appears. With a bit of filename parsing, you
can take it from there. Getting the whole DSO list, as per get_SO_realpaths,
before looking for any libstdc++ would let you detect, if you want, the freak possibility
of more than one libstdc++ being loaded.

How do I find what libraries need to be installed on a client linux machine if I compile a binary with a newer version of gcc?


What kind of things would need to be upgraded on the client box to run this new binary?

You will need to ship two shared libraries with your application: libgcc_s and libstdc++. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more details.

You can ship these libraries in the same directory with your executables if you link using $ORIGIN. See https://stackoverflow.com/a/4742034/412080 for more details.

And how would one find this out?

Run ldd and readelf -d on your executables to see what libraries they need.

from which version std::regex is available in libstdc++


I am packaging this software for Ubuntu, but can not figure out which version of libstdc++6 should I put as a dependency of my program.

The minimum dependency is the version that you linked your program with.

So if you linked with gcc-4.9.1 then they need at least libstdc++6-4.9.1

And what will be the dependency of this program for a general case regarding all Unix like OS that I should notify the user beforehand?

It needs a compiler that supports std::regex from C++11 ... but you already said that in the question.

Which version libstdc++.so is used in case of multiple GCC on the same system

I'm on Gentoo, which does support installing multiple versions of GCC at the same time. The libraries end up in /usr/lib/gcc/<target>/<version>. Ubuntu seems to install them in the same place, so I'd guess this to be a fairly common setup.

While gcc can apparently figure out the correct version to link against at compile time, the version used at runtime is configured using a file in /etc/ld.so.conf.d. So it might happen that a program gets compiled against one version of the gcc libraries, but executed with another.

If the ld.so.conf.d setting prefers newer versions over older, then this is mostly all right as long as gcc guys didn't introduce a new bug into one of these libraries, and as long as the configuration causes the libraries to be fully backwards-compatible.

In this bug we had a situation where libstdc++ broke backwards compatibility with regard to some C++11 features which were experimental and enabled using a custom configure switch. These things should be rare, but they can happen.

In a related gcc bug report I learned from Jonathan Wakely:

It is totally unsupported (and unlikely to work) to mix C++11 code built with GCC 4.x and 4.y, for any x!=y

Mixing code built with 4.8.x and 4.8.y should work, and does with the default configuration.

So while this setup works in practice on Gentoo, you are on your own if you try this yourself. Particularly since I know of no clean way to ensure that resulting binaries will link against the matching libraries at runtime.

You can try whether --program-suffix affects library names as well. If so, then the SONAME of the newer version libraries should be different from that of the older, helping to get the linking right at runtime. If the library name is unaffected, you could try examining the build system whether you can either change the SONAME of the generated libraries, or have the linker set the RPATH of all the programs it links. I have no experience with either of these approaches.

On Gentoo, /usr/bin/gcc appears to be some kind of wrapper, and the actual programs end up in /usr/<target>/gcc-bin/<version>/gcc and the likes. At least judging from the package web site, Ubuntu doesn't do this for the default version of gcc, although something similar is apparently used for cross-compilation to Android. I guess that setting is the result of a matching --bindir at configure time.

Link with an older version of libstdc++

You don't need to link to a different library, you need to use an older version of the compiler.

Have a look at the GNU ABI policy. The libstdc++ shared library is designed to be forward compatible. I.e. version 6.0.10 can be used if you need 6.0.8. In the policy you can read that from gcc-4.2.0 on, 6.0.9 is needed, so you need a gcc-4.1.x.

In short, that's why there's only one libstdc++.so.6.0.x on your system, you only need the latest.

As for setting up your build system to use only a specific version of the compiler: make sure the standard g++ can't be used (rename the link, remove the package providing it, take it out of PATH), and start digging. Worked for me.



Related Topics



Leave a reply



Submit