tcmalloc库使用测试

利用LD_PRELOAD来加载tcmalloc库
在编译时显式链接tcmalloc库
试验
试验1:不链接tcmalloc
试验2:仅显式链接tcmalloc
试验3:显式链接libc和tcmalloc,libc在前
试验4:显式链接libc和tcmalloc,tcmalloc在前
结论

利用LD_PRELOAD来加载tcmalloc库
那么用户调用malloc肯定是走到tcmalloc中;

在编译时显式链接tcmalloc库
如何保证在运行时,malloc符号是绑定到tcmalloc内的?
仅通过动态库加载顺序?还是有其它机制?

试验
x86_64平台。
写一个hello小程序,调用一次malloc函数。
利用如下命令来查看依赖库及malloc符号的绑定结果:
objdump -x a.out |grep NEEDED
LD_DEBUG=bindings ./a.out

试验1:不链接tcmalloc
[lubo@localhost hello]$ objdump a.out -x |grep NEEDED
NEEDED libc.so.6

[lubo@localhost hello]$ LD_DEBUG=bindings ./a.out
5363: initialize program: ./a.out
5363:
5363:
5363: transferring control: ./a.out
5363:
5363: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `malloc' [GLIBC_2.2.5]
5363: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]
5363:
5363: calling fini: ./a.out [0]


试验2:仅显式链接tcmalloc
[lubo@localhost hello]$ gcc hello.c -ltcmalloc
[lubo@localhost hello]$ objdump a.out -x |grep NEEDED
NEEDED libtcmalloc.so.4
NEEDED libc.so.6

[lubo@localhost hello]$ LD_DEBUG=bindings ./a.out
5414: initialize program: ./a.out
5414:
5414:
5414: transferring control: ./a.out
5414:
5414: binding file ./a.out [0] to /lib64/libtcmalloc.so.4 [0]: normal symbol `malloc'
5414: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]
5414:
5414: calling fini: ./a.out [0]


试验3:显式链接libc和tcmalloc,libc在前
[lubo@localhost hello]$ gcc hello.c -lc -ltcmalloc
[lubo@localhost hello]$ objdump a.out -x |grep NEEDED
NEEDED libc.so.6
NEEDED libtcmalloc.so.4

[lubo@localhost hello]$ LD_DEBUG=bindings ./a.out
5463: initialize program: ./a.out
5463:
5463:
5463: transferring control: ./a.out
5463:
5463: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `malloc' [GLIBC_2.2.5]
5463: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]
5463:
5463: calling fini: ./a.out [0]

试验4:显式链接libc和tcmalloc,tcmalloc在前
[lubo@localhost hello]$ gcc hello.c -ltcmalloc -lc
[lubo@localhost hello]$ objdump a.out -x |grep NEEDED
NEEDED libtcmalloc.so.4
NEEDED libc.so.6

[lubo@localhost hello]$ LD_DEBUG=bindings ./a.out
5501: initialize program: ./a.out
5501:
5501:
5501: transferring control: ./a.out
5501:
5501: binding file ./a.out [0] to /lib64/libtcmalloc.so.4 [0]: normal symbol `malloc'
5501: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]
5501:
5501: calling fini: ./a.out [0]

结论
经过上述测试验证(也作了libstdc++ / new函数的测试),
当显式链接libtcmalloc时,进程的malloc/new最终能不能调到tcmalloc中,取决于进程对动态库的依赖顺序。
如果编译软件时,既显式链接libc(或libstdc++),又显式链接libtcmalloc,那么必须保证先链接tcmalloc再链接libc(或libstdc++),否则,malloc/new函数还是被绑定到原生的libc(或libstdc++)中。

延伸:
进程加载多个依赖库时,可以选择广度优先遍历加载,也可以选择深度优先遍历加载,不同的加载策略,会导致某些动态库的加载顺序发生变化,如果多个动态库中含有相同的动态符号,那么会产生不同的符号绑定结果。但对于tcmalloc来说,只要不显示链接libc(或libstdc++),一般就没什么问题,因为不管广度优先还是深度优先,tcmalloc必然在libc(libstdc++)之前先被加载。
————————————————
版权声明:本文为CSDN博主「bobbypollo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bobbypollo/article/details/79906985

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值