我在 RedHat Linux 5.0 上有一个内部共享库,它提供free
以下功能malloc
:
>nm ./libmem_consumption.so | grep -P -e "\bfree\b|\bmalloc\b"
0000000000006540 T free
00000000000088a0 T malloc
这个共享库负责提供有关进程内存消耗的信息。不幸的是,这个共享库在与 Apache 一起使用时出现了问题httpd
。当 Apache httpd 与这个库一起运行时,我得到一个核心转储libc::free
和一条指针无效的消息。问题似乎出在 http.so 中,这是一个由 libphp5.so 加载的共享库,由httpd
.
实际上,当我不加载时,http.so
一切正常并且没有核心转储。(加载或不加载http.so
由配置文件中的指令管理:extension=http.so)当我加载http.so
httpd 进程 coredumps。
httpd
以这种方式启动:
LD_PRELOAD=./libmem_consumption.so ./bin/httpd -f config
和退出时的核心转储。
当我设置 LD_BIND_NOW=1 并http.so
加载时,我看到(在 gdb 下)http.sofree@plt
指向libc::free
并在其他加载的库中(例如libphp5.so
)free@plt
指向libmem_consumption.so::free
. 这怎么可能?
顺便说一句,当我导出 LD_DEBUG=all 并将输出保存到文件时,我看到 libphp5.so 的这些行(也已加载):
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]
和 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'
似乎LD_PRELOAD=./libmem_consumption.so
不用于http.so
何时free
查找。为什么 LD_PRELOAD 被忽略?