Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect library features at runtime in C

I am trying to build a program in C which has a lot of optional features that depend on various shared libraries.

In our heterogeneous computing cluster not all of those libraries are available (or up to date) on all systems.

Examples are symbols from newer glibc (sched_getcpu@@GLIBC_2.6, __sched_cpucount@@GLIBC_2.6) or whole shared libraries which may or may not be available (libnuma, libR, libpbs).

I know that I can use libdl to load the symbols with dlopen and dlsym, but doing this for an ever growing number of symbols (around 30 at the moment) is tedious at best.

As far as I understand shared libraries in Linux are lazy-loaded by default, so a symbol should not be needed until it is actually used.

But if I try to check for that in advance then it fails at execution start:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include <sched.h>

int main() {

    void *lib_handle;
    int (*fn)(void);
    int x;
    char *error;

    lib_handle = dlopen("libc.so.6", RTLD_LAZY);
    if (!lib_handle) 
    {
       fprintf(stderr, "%s\n", dlerror());
       exit(1);
    }

    fn = dlsym(lib_handle, "sched_getcpu");
    if ((error = dlerror()) != NULL)  
    {
       fprintf(stderr, "%s\n", error);
       exit(1);
    }

    printf("%d\n", sched_getcpu());

    return 0;
}

On compile system which has all libraries:

$ icc test.c
$ ./a.out
10

On another system which has a less recent version of GLIBC:

$ ./a.out 
./a.out: /lib64/libc.so.6: version `GLIBC_2.6' not found (required by ./a.out)

If I comment out the line that actually calls sched_getcpu then I get instead on the lesser system:

$ ./a.out 
/lib64/libc.so.6: undefined symbol: sched_getcpu

So, is there a way to force libraries only to be loaded on use and have checks like these before blocks that use them?

like image 836
Sergey L. Avatar asked Dec 18 '12 18:12

Sergey L.


People also ask

What is runtime library in C?

The C runtime library is a collection of subroutines that are needed to build a program in C. The subroutines can basically be put into 2 categories: C standard library. Compiler-specific auxiliary functions.

How are library functions accessed in C?

A library function is accessed by simply writing the function name, followed by a list of arguments, which represent the information being passed to the function. The arguments must be enclosed in parentheses, and separated by commas: they can be constants, variables, or more complex expressions.

Which library helps us to provide runtime details of our application?

Open Source, Embedded Linux, and Android The compiler support library is called libgcc and is provided by the compiler itself to supply low-level compiler support routines such as software floating-point emulation and support for exception-handling. This library is used by virtually all programs compiled with GCC.

Where are library functions stored in C?

C Standard library functions or simply C Library functions are inbuilt functions in C programming. The prototype and data definitions of these functions are present in their respective header files. To use these functions we need to include the header file in our program.


1 Answers

Not with glibc. This is a fail-safe and it's in place so that you won't shoot yourself in the foot. If the GLIBC_2.6 symbol wasn't defined and looked up, even if there were no other missing symbols, you could get garbage results from glibc (data corruption and crashes,) since it's not forwards compatible.

If you need compatibility on the glibc level, you need to build against the lowest common version.

like image 144
Nikos C. Avatar answered Oct 05 '22 12:10

Nikos C.