I downloaded the glibc source code, modified some portion of the standard library and then used LD_PRELOAD to use that modified standard library (in the form of an .so file) with my program. However, when I copied that .so file to another computer and tried to run the same program using LD_PRELOAD there, I got a segmentation fault.
Notice that both computers have x86-64 processors. Moreover, both computers have gcc 4.4 installed. Although the computer in which it is not running has also gcc 4.1.2 installed besides gcc 4.4. However, one is running Ubuntu 10.04 (where I compiled), while the other is running CentOS 5. Is that the cause of the segmentation fault? How can I solve this problem? Notice that I don’t have administrative rights on the computer with CentOS 5.
When you LD_PRELOAD the C library, I believe you’re loading it in addition to the default C library. When they’re the exact same version, all the symbols match, and yours takes precedence. So it works. When they’re different versions, you may well have a mix, on a per-symbol basis.
Also, the NSS (name service switch, e.g., all the stuff from /etc/nsswitch.conf) API is not stable. These modules are separate from the main libc.so, but are dynamically loaded when a program e.g., does a user id to username mapping. Loading the wrong version (because you copied libc.so over) will do all kinds of badness.
Further, Ubuntu may be using eglibc and CentOS glibc. So you could be looking at a different fork of glibc.
If your LD_PRELOAD library included only the symbols you actually need to override, and overrode them to the minimum amount possible (e.g., if possible, call the overridden function), then your library has a much higher chance of being portable.
For an example of how to do this, see (for example) fakeroot.
If you’re changing so much of libc that your only choice is to override all of it, then (a) you’re doing something very weird; (b) you probably want to use
LD_LIBRARY_PATH, notLD_PRELOAD; see the ld.so(8) manpage for details.