Linux動態鏈接庫同名符號裝載問題(二)

上一篇《Linux動態鏈接庫同名符號裝載問題(一)》中提到了動態鏈接的一些問題,本文主要討論動態加載時符號衝突的問題。

PART1:RTLD_DEEPBIND打開動態鏈接導致段錯誤的現象

可執行程序A通過dlopen動態加載library.so,有可能出現library.so中和這樣的情況:

 

程序A中存在函數search_hash()
library.so中同樣存在函數search_hash()


dlopen使用默認參數情況下,程序A中的search_hash已經加載到全局符號表,當library.so中某個函數想調用search_hash時,實際會調用到進程A中的search_hash函數。爲了保證library.so能夠優先調用到自己的函數,可以在dlopen時使用RTLD_DEEPBIND參數,優先調用.so內部的參數。

但是,在使用RTLD_DEEPBIND參數打開在某些使用libstdc++的動態鏈接庫是會發生段錯誤。

GCC網站上的這個BUG report很詳細的描述了該現象。

另一個BUG report中的分析,是由於程序啓動時會初始化libstdc++,但是當dlopen某個動態鏈接庫,因爲使用了RTLD_DEEPBIND參數,動態鏈接庫內部調用libstdc++中的函數時會被定爲到一個未初始化的實例,引起段錯誤。

尚未找到該問題的解決方案。

PART2:動態加載的鏈接庫衝突符號如何定位?

在某些情況下.so之間也存在依賴,例如還存在另一個library2.so依賴於library.so中的一些函數,就要求在dlopen打開library.so時添加RTLD_GLOBAL參數,將library.so的符號表全局打開。這樣有可能造成程序A和library.so中符號名衝突,由於這個衝突時在運行時發生的,很不容易調試。這裏提供一個可以在運行前檢查的方法:

 

nm A|awk '{if ($2=="T") print $3}'> symbol
nm library.so|awk '{if ($2=="T") print $3}'>> symbol
cat symbol|sort|uniq -c>collision_symbol


在collision_symbol文件中出現次數大於1的符號就是發生衝突的。

 

這篇文章很好的分析了Linux動態鏈接庫的機制:http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/index.html

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