Skip to main content

Override the GNU C library -- painlessly

Debug systems problems and make quick fixes

Jay Allen (jaydallen@us.ibm.com), Programmer, IBM
Jay Allen is a programmer in IBM's Linux for Service Providers Lab (LSPL). You can contact Jay at jaydallen@us.ibm.com.

Summary:  A great way to debug glibc functions is to override the function of interest with your own version. This can be done without having root permissions and without recompiling the libc source. Imagine the pure thrill of writing your own version of open()!

Date:  01 Apr 2002
Level:  Introductory
Activity:  3556 views

What do you do if you don't have the source for your application and it's failing because a GNU Library for C (glibc) function is returning something bad to the application? Because glibc is open-source, you can of course get the source code, make your changes, rebuild, and install. This is not for the faint of heart, however, because although the API is well documented, the internal organization of the GNU C library is not. Finding the correct function prototypes is only the first of many challenges. It's a big package as well, so the first time you compile, it will take some time (glibc 2.2.2 has 8,552 files and 1,775,440 lines of code, including comments).

A better way

Better than rebuilding glibc is selectively overriding a function. Many of the modern Unixes support the concept of preloading user defined libraries. These libraries can be either complete replacements (that is, a private version of glibc) or subsets -- even a single function. You can use a private version of glibc by setting the LD_LIBRARY_PATH to include your private version of the library first. You can use a subset of library routines that you write by using the LD_PRELOAD environmental value. Both LD_LIBRARY_PATH and LD_PRELOAD are controlled by the dynamic ELF linker/loader. It uses a first match to satisfy any symbol name. By preloading your version of a library or function you short circuit the normal path, allowing you to override it.

Here's an example makefile that overrides the glibc function setresgid():


Makefile to override setresgid()

 #
 # Makefile 
 #

 all: libs setresgid-tester

 #
 # Make a shared Library
 #
 libs: libfuncs.c
         gcc -shared -Wl,-soname,libfuncs.so.1 -o libfuncs.so.1.0  libfuncs.c 
         ln -s libfuncs.so.1.0 libfuncs.so.1
         ln -s libfuncs.so.1 libfuncs.so

 #
 # Here is a program that calls setresgid() for testing
 #
 setresgid-tester: setresgid-tester.c
         gcc -o setresgid-tester setresgid-tester.c

The file libfuncs.c contains my private version of setresgid(). Be careful to implement it to support the same number of arguments and in other ways act the same as the original setresgid(), although my version lies to the application and always returns 0.

The second file of interest is setresgid-tester.c. It tries out the new function by calling setresgid().

This is the source code for the dynamic library:


Replacement library

 /*
  Put all the functions you want to override here
 */
 #include <sys/types.h>
 #include <unistd.h>
 #include <errno.h>

 int errno;

 int 
 setresgid(rgid, egid, sgid)
         gid_t rgid,egid,sgid;
 {
    errno=1; 
    printf("It me the shim, Hi there!\n");
    return(0);

 }

You'll also need a simple way to test your private version of setresgid(). You can use strace or ltrace to watch the process run. This is the source for a trivial test example:


Trivial test example

 /* 
   setresgid() system/library call tester 
 */
 #include 
 #include 
 main(){
    setresgid(0,0,0);
 }

Now compile the library, set the LD_PRELOAD shell variable and run the test application. You may also need to set your LD_LIBRARY_PATH.


Running test application

export LD_PRELOAD=libfuncs.so
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./setresgid-tester
It's me the shim, Hi there!

You can also confirm that your private library is being used by using ldd to list the dynamically linked libraries:


Confirming use of private library

[jay@prion ld_preload]$ ldd setresgid-tester
        libfuncs.so => libfuncs.so (0x40018000)
        libc.so.6 => /lib/libc.so.6 (0x40022000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)


Conclusion

Writing private versions of GNU C library functions is a great way to debug systems problems or make quick fixes. Using the LD_PRELOAD shell variable, you can selectively override system C library functions with your own private versions. This technique works for both Linux and Solaris environments.


About the author

Jay Allen is a programmer in IBM's Linux for Service Providers Lab (LSPL). You can contact Jay at jaydallen@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux, Open source
ArticleID=11206
ArticleTitle=Override the GNU C library -- painlessly
publish-date=04012002
author1-email=jaydallen@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers