- Linux Commands For Shared Library Management & Debugging Problem
- What is a Library In Linux or UNIX?
- Linux Library Management Commands
- Important Files
- #1: ldconfig command
- Examples
- Troubleshooting Chrooted Jails
- Rootkits
- Common errors
- Can’t find library xyz Error
- #2: ldd command
- Understanding Shared Libraries in Linux
- Shared Library Naming Conventions
- Locating Shared Libraries in Linux
- Managing Shared Libraries in Linux
- If You Appreciate What We Do Here On TecMint, You Should Consider:
- Shared libraries with GCC on Linux
- Step 1: Compiling with Position Independent Code
- Step 2: Creating a shared library from an object file
- Step 3: Linking with a shared library
- Telling GCC where to find the shared library
- Step 4: Making the library available at runtime
- Using LD_LIBRARY_PATH
- Using rpath
- rpath vs. LD_LIBRARY_PATH
- Using ldconfig to modify ld.so
Linux Commands For Shared Library Management & Debugging Problem
I f you are a developer, you will re-use code provided by others. Usually /lib, /lib64, /usr/local/lib, and other directories stores various shared libraries. You can write your own program using these shared libraries. As a sys admin you need to manage and install these shared libraries. Use the following commands for shared libraries management, security, and debugging problems.
What is a Library In Linux or UNIX?
In Linux or UNIX like operating system, a library is noting but a collection of resources such as subroutines / functions, classes, values or type specifications. There are two types of libraries:
- Static libraries – All lib*.a fills are included into executables that use their functions. For example you can run a sendmail binary in chrooted jail using statically liked libs.
- Dynamic libraries or linking [ also known as DSO (dynamic shared object)] – All lib*.so* files are not copied into executables. The executable will automatically load the libraries using ld.so or ld-linux.so.
Linux Library Management Commands
- ldconfig : Updates the necessary links for the run time link bindings.
- ldd : Tells what libraries a given program needs to run.
- ltrace : A library call tracer.
- ld.so/ld-linux.so: Dynamic linker/loader.
Important Files
As a sys admin you should be aware of important files related to shared libraries:
- /lib/ld-linux.so.* : Execution time linker/loader.
- /etc/ld.so.conf : File containing a list of colon, space, tab, newline, or comma separated directories in which to search for libraries.
- /etc/ld.so.cache : File containing an ordered list of libraries found in the directories specified in /etc/ld.so.conf. This file is not in human readable format, and is not intended to be edited. This file is created by ldconfig command.
- lib*.so.version : Shared libraries stores in /lib, /usr/lib, /usr/lib64, /lib64, /usr/local/lib directories.
#1: ldconfig command
You need to use the ldconfig command to create, update, and remove the necessary links and cache (for use by the run-time linker, ld.so) to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/usr/lib, /lib64 and /lib). The ldconfig command checks the header and file names of the libraries it encounters when determining which versions should have their links updated. This command also creates a file called /etc/ld.so.cache which is used to speed up linking.
Examples
In this example, you’ve installed a new set of shared libraries at /usr/local/lib/:
$ ls -l /usr/local/lib/
Sample outputs:
Now when you run an app related to libGeoIP.so, you will get an error about missing library. You need to run ldconfig command manually to link libraries by passing them as command line arguments with the -l switch:
# ldconfig -l /path/to/lib/our.new.lib.so
Another recommended options for sys admin is to create a file called /etc/ld.so.conf.d/geoip.conf as follows:
Now just run ldconfig to update the cache:
# ldconfig
To verify new libs or to look for a linked library, enter:
# ldconfig -v
# ldconfig -v | grep -i geoip
Sample outputs:
Troubleshooting Chrooted Jails
You can print the current cache with the -p option:
# ldconfig -p
Putting web server such as Apache / Nginx / Lighttpd in a chroot jail minimizes the damage done by a potential break-in by isolating the web server to a small section of the filesystem. It is also necessary to copy all files required by Apache inside the filesystem rooted at /jail/ directory , including web server binaries, shared Libraries, modules, configuration files, and php/perl/html web pages. You need to also copy /etc/
Rootkits
A rootkit is a program (or combination of several programs) designed to take fundamental control of a computer system, without authorization by the system’s owners and legitimate managers. Usually, rootkit use /lib, /lib64, /usr/local/lib directories to hide itself from real root users. You can use ldconfig command to view all the cache of all shared libraries and unwanted programs:
# /sbin/ldconfig -p | less
You can also use various tools to detect rootkits under Linux.
Common errors
You may see the errors as follows:
Dynamic linker error in foo
Can’t map cache file cache-file
Cache file cache-file foo
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
All of the above errors means the linker cache file /etc/ld.so.cache is corrupt or does not exists. To fix these errors simply run the ldconfig command as follows:
# ldconfig
Can’t find library xyz Error
The executable required a dynamically linked library that ld.so or ld-linux.so cannot find. It means a library called xyz needed by the program called foo not installed or path is not set. To fix this problem install xyz library and set path in /etc/ld.so.conf file or create a file in /etc/ld.so.conf.d/ directory.
#2: ldd command
ldd (List Dynamic Dependencies) is a Unix and Linux program to display the shared libraries required by each program. This tools is required to build and run various server programs in a chroot jail. A typical example is as follows to list the Apache server shared libraries, enter:
# ldd /usr/sbin/httpd
Sample outputs:
Now, you can copy all those libs one by one to /jail directory
Источник
Understanding Shared Libraries in Linux
In programming, a library is an assortment of pre-compiled pieces of code that can be reused in a program. Libraries simplify life for programmers, in that they provide reusable functions, routines, classes, data structures and so on (written by a another programmer), which they can use in their programs.
For instance, if you are building an application that needs to perform math operations, you don’t have to create a new math function for that, you can simply use existing functions in libraries for that programming language.
Examples of libraries in Linux include libc (the standard C library) or glibc (GNU version of the standard C library), libcurl (multiprotocol file transfer library), libcrypt (library used for encryption, hashing, and encoding in C) and many more.
Linux supports two classes of libraries, namely:
- Static libraries – are bound to a program statically at compile time.
- Dynamic or shared libraries – are loaded when a program is launched and loaded into memory and binding occurs at run time.
Dynamic or shared libraries can further be categorized into:
- Dynamically linked libraries – here a program is linked with the shared library and the kernel loads the library (in case it’s not in memory) upon execution.
- Dynamically loaded libraries – the program takes full control by calling functions with the library.
Shared Library Naming Conventions
Shared libraries are named in two ways: the library name (a.k.a soname) and a “filename” (absolute path to file which stores library code).
For example, the soname for libc is libc.so.6: where lib is the prefix, c is a descriptive name, so means shared object, and 6 is the version. And its filename is: /lib64/libc.so.6. Note that the soname is actually a symbolic link to the filename.
Locating Shared Libraries in Linux
Shared libraries are loaded by ld.so (or ld.so.x) and ld-linux.so (or ld-linux.so.x) programs, where x is the version. In Linux, /lib/ld-linux.so.x searches and loads all shared libraries used by a program.
A program can call a library using its library name or filename, and a library path stores directories where libraries can be found in the filesystem. By default, libraries are located in /usr/local/lib, /usr/local/lib64, /usr/lib and /usr/lib64; system startup libraries are in /lib and /lib64. Programmers can, however, install libraries in custom locations.
The library path can be defined in /etc/ld.so.conf file which you can edit with a command line editor.
The line(s) in this file instruct the kernel to load file in /etc/ld.so.conf.d. This way, package maintainers or programmers can add their custom library directories to the search list.
If you look into the /etc/ld.so.conf.d directory, you’ll see .conf files for some common packages (kernel, mysql and postgresql in this case):
If you take a look at the mariadb-x86_64.conf, you will see an absolute path to package’s libraries.
The method above sets the library path permanently. To set it temporarily, use the LD_LIBRARY_PATH environment variable on the command line. If you want to keep the changes permanent, then add this line in the shell initialization file /etc/profile (global) or
/.profile (user specific).
Managing Shared Libraries in Linux
Let us now look at how to deal with shared libraries. To get a list of all shared library dependencies for a binary file, you can use the ldd utility. The output of ldd is in the form:
This command shows all shared library dependencies for the ls command.
Sample Output
Because shared libraries can exist in many different directories, searching through all of these directories when a program is launched would be greatly inefficient: which is one of the likely disadvantages of dynamic libraries. Therefore a mechanism of caching employed, performed by a the program ldconfig.
By default, ldconfig reads the content of /etc/ld.so.conf, creates the appropriate symbolic links in the dynamic link directories, and then writes a cache to /etc/ld.so.cache which is then easily used by other programs.
This is very important especially when you have just installed new shared libraries or created your own, or created new library directories. You need to run ldconfig command to effect the changes.
After creating your shared library, you need to install it. You can either move it into any of the standard directories mentioned above, and run the ldconfig command.
Alternatively, run the following command to create symbolic links from the soname to the filename:
To get started with creating your own libraries, check out this guide from The Linux Documentation Project(TLDP).
Thats all for now! In this article, we gave you an introduction to libraries, explained shared libraries and how to manage them in Linux. If you have any queries or additional ideas to share, use the comment form below.
If You Appreciate What We Do Here On TecMint, You Should Consider:
TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.
If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.
We are thankful for your never ending support.
Источник
Shared libraries with GCC on Linux
Libraries are an indispensable tool for any programmer. They are pre-existing code that is compiled and ready for you to use. They often provide generic functionality, like linked lists or binary trees that can hold any data, or specific functionality like an interface to a database server such as MySQL.
Most larger software projects will contain several components, some of which you may find use for later on in some other project, or that you just want to separate out for organizational purposes. When you have a reusable or logically distinct set of functions, it is helpful to build a library from it so that you do not have to copy the source code into your current project and recompile it all the time — and so you can keep different modules of your program disjoint and change one without affecting others. Once it is been written and tested, you can safely reuse it over and over again, saving the time and hassle of building it into your project every time.
Building static libraries is fairly simple, and since we rarely get questions on them, I will not cover them. I will stick with shared libraries, which seem to be more confusing for most people.
Before we get started, it might help to get a quick rundown of everything that happens from source code to running program:
- C Preprocessor: This stage processes all the preprocessor directives. Basically, any line that starts with a #, such as #define and #include.
- Compilation Proper: Once the source file has been preprocessed, the result is then compiled. Since many people refer to the entire build process as compilation, this stage is often referred to as compilation proper. This stage turns a .c file into an .o (object) file.
- Linking: Here is where all of the object files and any libraries are linked together to make your final program. Note that for static libraries, the actual library is placed in your final program, while for shared libraries, only a reference to the library is placed inside. Now you have a complete program that is ready to run. You launch it from the shell, and the program is handed off to the loader.
- Loading: This stage happens when your program starts up. Your program is scanned for references to shared libraries. Any references found are resolved and the libraries are mapped into your program.
Steps 3 and 4 are where the magic (and confusion) happens with shared libraries.
Now, on to our (very simple) example.
foo.h defines the interface to our library, a single function, foo(). foo.c contains the implementation of that function, and main.c is a driver program that uses our library.
For the purposes of this example, everything will happen in /home/username/foo
Step 1: Compiling with Position Independent Code
We need to compile our library source code into position-independent code (PIC): 1
Step 2: Creating a shared library from an object file
Now we need to actually turn this object file into a shared library. We will call it libfoo.so:
Step 3: Linking with a shared library
As you can see, that was actually pretty easy. We have a shared library. Let us compile our main.c and link it with libfoo. We will call our final program test. Note that the -lfoo option is not looking for foo.o, but libfoo.so. GCC assumes that all libraries start with lib and end with .so or .a (.so is for shared object or shared libraries, and .a is for archive, or statically linked libraries).
Telling GCC where to find the shared library
Uh-oh! The linker does not know where to find libfoo. GCC has a list of places it looks by default, but our directory is not in that list. 2 We need to tell GCC where to find libfoo.so. We will do that with the -L option. In this example, we will use the current directory, /home/username/foo:
Step 4: Making the library available at runtime
Good, no errors. Now let us run our program:
Oh no! The loader cannot find the shared library. 3 We did not install it in a standard location, so we need to give the loader a little help. We have a couple of options: we can use the environment variable LD_LIBRARY_PATH for this, or rpath. Let us take a look first at LD_LIBRARY_PATH:
Using LD_LIBRARY_PATH
There is nothing in there. Let us fix that by prepending our working directory to the existing LD_LIBRARY_PATH:
What happened? Our directory is in LD_LIBRARY_PATH, but we did not export it. In Linux, if you do not export the changes to an environment variable, they will not be inherited by the child processes. The loader and our test program did not inherit the changes we made. Thankfully, the fix is easy:
Good, it worked! LD_LIBRARY_PATH is great for quick tests and for systems on which you do not have admin privileges. As a downside, however, exporting the LD_LIBRARY_PATH variable means it may cause problems with other programs you run that also rely on LD_LIBRARY_PATH if you do not reset it to its previous state when you are done.
Using rpath
Now let s try rpath (first we will clear LD_LIBRARY_PATH to ensure it is rpath that is finding our library). Rpath, or the run path, is a way of embedding the location of shared libraries in the executable itself, instead of relying on default locations or environment variables. We do this during the linking stage. Notice the lengthy “-Wl,-rpath=/home/username/foo” option. The -Wl portion sends comma-separated options to the linker, so we tell it to send the -rpath option to the linker with our working directory.
Excellent, it worked. The rpath method is great because each program gets to list its shared library locations independently, so there are no issues with different programs looking in the wrong paths like there were for LD_LIBRARY_PATH.
rpath vs. LD_LIBRARY_PATH
There are a few downsides to rpath, however. First, it requires that shared libraries be installed in a fixed location so that all users of your program will have access to those libraries in those locations. That means less flexibility in system configuration. Second, if that library refers to a NFS mount or other network drive, you may experience undesirable delays — or worse — on program startup.
Using ldconfig to modify ld.so
What if we want to install our library so everybody on the system can use it? For that, you will need admin privileges. You will need this for two reasons: first, to put the library in a standard location, probably /usr/lib or /usr/local/lib, which normal users do not have write access to. Second, you will need to modify the ld.so config file and cache. As root, do the following:
Now the file is in a standard location, with correct permissions, readable by everybody. We need to tell the loader it is available for use, so let us update the cache:
That should create a link to our shared library and update the cache so it is available for immediate use. Let us double check:
Now our library is installed. Before we test it, we have to clean up a few things:
Clear our LD_LIBRARY_PATH once more, just in case:
Re-link our executable. Notice we do not need the -L option since our library is stored in a default location and we are not using the rpath option:
Let us make sure we are using the /usr/lib instance of our library using ldd:
Good, now let us run it:
That about wraps it up. We have covered how to build a shared library, how to link with it, and how to resolve the most common loader issues with shared libraries — as well as the positives and negatives of different approaches.
- It looks in the DT_RPATH section of the executable, unless there is a DT_RUNPATH section.
- It looks in LD_LIBRARY_PATH. This is skipped if the executable is setuid/setgid for security reasons.
- It looks in the DT_RUNPATH section of the executable unless the setuid/setgid bits are set (for security reasons).
- It looks in the cache file /etc/ld/so/cache (disabled with the -z nodeflib linker option).
- It looks in the default directories /lib then /usr/lib (disabled with the -z nodeflib linker option).
What is position independent code? PIC is code that works no matter where in memory it is placed. Because several different programs can all use one instance of your shared library, the library cannot store things at fixed addresses, since the location of that library in memory will vary from program to program. ↩
GCC first searches for libraries in /usr/local/lib, then in /usr/lib. Following that, it searches for libraries in the directories specified by the -L parameter, in the order specified on the command line. ↩
Источник