Fun with LD_PRELOAD
LD_PRELOAD is a useful mechanism provided by many dynamic linkers (including the GNU C library (glibc)). It enables users to specify additional shared libraries that are loaded when executing dynamically linked programs. Typically these preloaded libraries will override or intercept functions defined by other (regular) shared libraries. This allows the behaviour of existing programs and libraries to be modified non-invasively, that is, without requiring recompilation or relinking. Some of the creative applications of this powerful technique include:
1. Filesystem shenanigans, for example, presenting a modified view of the filesystem, or logging all filesystem accesses.
2. Network shenanigans, for example, preventing programs from accessing the network, or limiting their access.
3. Debugging and testing, for example, causing memory allocation or IO to deliberately fail to test graceful error handling.
4. Annoyance reduction, for example, intercepting terminal beeping.
5. Library tracing and logging, similar to ltrace/strace.
6. Graphical augmentation, for example, adding a frames-per-second (fps) display to OpenGL applications.
7. Reverse-engineering, extending and modifying the behaviour of closed-source software, for example, adding awareness of cpusets to proprietary (but hardware-optimised) MPI libraries provided by HPC vendors.
This presentation is aimed at people who are C programmers (or at least familiar with C) and are interested in learning about LD_PRELOAD. Practical code examples will be given, and live demos shown (where possible and appropriate).
There are four main sections of the presentation. First is a broad overview of dynamic linking and LD_PRELOAD, and its advantages, disadvantages, applicability and limitations. This is followed by a review of existing LD_PRELOAD applications in the areas mentioned above.
The third section shows how write LD_PRELOAD-oriented C code. This includes skeletal code and the basic structure of a function-intercepting LD_PRELOAD library, motivated by the in-presentation development of a simple LD_PRELOAD library (with example autoconf/automake compilation code).
The final section will demonstrate a non-trivial application of LD_PRELOAD to X Windows applications, namely, xmultiwin and xlibtrace. xmultiwin is a preload library that transparently "clones" X11 windows. This allows unmodified X11 applications to be displayed simultaneously (and interacted with) in multiple windows, for example, one on each monitor of a multi-monitor Xinerama setup. xlibtrace is a library for the X11 client library interface (libX11 and friends). It is similar to ltrace/strace, except that it is specifically optimised for the X11 library, and is similar to xtrace except that it traces communication between the application and the X11 client library, not just communication between the X11 client and server. Both of these projects additionally feature heavy use of automatic code generation using C preprocessor macros and shell scripting.
Kevin Pulo is an Academic Consultant and Systems Programmer at the APAC National Facility and ANU Supercomputing Facility, where he works on scientific computing, information visualisation and HPC system issues such as MPI, cpusets and batch scheduling. He completed his PhD in the field of Information Visualisation at the University of Sydney and National ICT Australia (NICTA) in 2004.
His interests include information visualisation (particularly interactive and animated visualisations), parallel programming, HPC system management and human-computer interaction (particularly multi-monitor desktop/window management and usability). He has used Slackware since version 3.0 and runs a highly customised fvwm1 based X Windows environment.