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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章