小編給大家分享一下linux下同名符號沖突怎么辦,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
linux 下同名符號沖突問題解決方案
最近的工作中遇到如下令人蛋疼的問題:
Linux 下有三個模塊aa、bb、cc,基本情況如下:
cc 編譯連接得到 cc.so 動態庫,cc 中有如下接口:
cc_fun
{
……
do();//調用名為do的cc模塊內部函數
……
}bb 編譯連接得到 bb.a 靜態庫,bb 中有如下接口:
bb_fun
{
……
handle = dlopen(cc.so, RTLD_LAZY);//加載cc.so
pccfun = dlsym(handle, “cc_fun”);//獲取cc_fun函數指針
(*pccfun)();//調用cc_fun函數,此時應該會調用cc模塊中的do()函數
do();//調用名為do的bb模塊內部函數(與cc模塊中的do()函數同名,實現卻不相同)
……
}aa 編譯后通過 -lbb 鏈接選項的方式連接 bb.a 得到 aa 可執行程序,并調用 bb.a 的接口函數 bb_fun():
main
{
……
bb_fun();//調用bb_fun函數
……
}工作中發現 aa 在運行時行為異常,總是有內存泄露和功能異常,通過定位發現問題集中在同名的 do() 函數上。通過輸出打印發現程序中兩次調用 do() 函數都調用到了 bb 模塊中的 do() 函數,而 cc 模塊中的 do() 函數從未被調用到,導致程序行為異常和內存泄露。
后經多方查證了解到因為 linux 程序中各個庫中的符號表最終都會加載到程序所在的全局符號表中,此時如果有同名符號就只能調用到第一個加載進來的符號,也就是說后邊加載的同名符號都會被之前的覆蓋。cc 模塊中的 do() 函數被 bb 模塊中的 do() 函數覆蓋了,所以無法被調用到。
廢話不多說。。。
在試驗過很多不滿意的方法之后,最終的解決方法如下:
1.在 cc 的 makefile 中加入 -Wl,-Bsymbolic -Wl,--version-script,version 的連接選項,意思是用 version 文件中的腳本指定其導出哪些函數。
2.version 文件的實現如下:
VERS{
global:
cc_fun;
local: *;
};意思是指定 cc 模塊只導出接口函數 cc_fun,其余函數都設為 local 不做導出。
將該文件保存在 makefile 所在目錄即可。
3.重新編譯連接三個模塊,問題解決。
以上是“linux下同名符號沖突怎么辦”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。