Zulan
Zulan

Reputation: 22670

Reading libstdc++ version at runtime

My application is affected by a bug in older versions of libstdc++ in a rather serious data-lossy way. The remedies of how to select the right library version with -rpath or LD_LIBRARY_PATH are known, but not reliable to changes in deployment and build. After being bitten more than once myself I would like to stop the suffering and introduce a runtime-check for a sufficiently new version of libstdc++. How can I access the version in order to print a big fat warning message in case of the deployment failing to use the right version. Note that I need the minor version libstdc++.so.6.0.25 a.k.a. GLIBCXX_3.4.25 that comes with gcc 8.

Upvotes: 4

Views: 1671

Answers (1)

Mike Kinghan
Mike Kinghan

Reputation: 61515

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.

Upvotes: 5

Related Questions