I have an in-house shared library on RedHat Linux 5.0 that provides functions free
and malloc
:
>nm ./libmem_consumption.so | grep -P -e "\bfree\b|\bmalloc\b"
0000000000006540 T free
00000000000088a0 T malloc
This shared library is responsible for providing information about memory consumption of a process.
Unfortunatelly there is a problem with this shared library when it is used with Apache httpd
.
When Apache httpd is run with this library I get a coredump in libc::free
and a message that the pointer is invalid.
The problem seems to be in http.so which is a shared library loaded by libphp5.so that is loaded by the httpd
.
Actually when I do not load http.so
everything is OK and there is no coredump.
(Loading or not loading http.so
is managed by the directive in a configuration file: extension=http.so)
When I load http.so
the httpd process coredumps.
httpd
is lauched in this way:
LD_PRELOAD=./libmem_consumption.so ./bin/httpd -f config
and coredumps on exit.
When I set LD_BIND_NOW=1 and http.so
is loaded I see (under gdb) that http.so has free@plt
pointing to libc::free
and in in other loaded
libraries (for example libphp5.so
) free@plt
points to libmem_consumption.so::free
.
How that could be possible?
By the way when I export LD_DEBUG=all and save output to a file I see these lines for libphp5.so (which is also loaded):
25788: symbol=free; lookup in file=/apache2/bin/httpd [0]
25788: symbol=free; lookup in file=/apache2/ps/lib/libmem_consumption.so [0]
25788: binding file /apache2/modules/libphp5.so [0] to /apache2/ps/lib/libmem_consumption.so [0]: normal symbol `free' [GLIBC_2.2.5]
And completely different for http.so:
25825: symbol=free; lookup in file=/apache2/ext/http.so [0]
25825: symbol=free; lookup in file=/apache2/ps/lib/libz.so.1 [0]
25825: symbol=free; lookup in file=/apache2/ps/lib/libcurl.so.4 [0]
25825: symbol=free; lookup in file=/lib64/libc.so.6 [0]
25825: binding file /apache2/ext/http.so [0] to /lib64/libc.so.6 [0]: normal symbol `free'
It seems that LD_PRELOAD=./libmem_consumption.so
is not used for http.so
when free
is looked up. Why LD_PRELOAD is ignored?
It seeems that http.so is loaded with the RTLD_DEEPBIND flag and that is why LD_PRELOAD is ignored for one of shared libraries.
This is from http://linux.die.net/man/3/dlopen:
I wrote a test shared library:
And built it:
When I set UNSET_RTLD_DEEPBIND to 0 and run
httpd
the program coredumps.When I set UNSET_RTLD_DEEPBIND to 1 and run
httpd
everything is OK.And this is the output of LD_DEBUG=all for the UNSET_RTLD_DEEPBIND to 1: