Linux迭代呼叫共享動態庫導致segment fault
專案需要我編寫了一個動態庫libs2cShareLib.so供同組同事Carson使用,他也也編了一個動態庫libnative.so,並在這個庫內部使用我提供的介面。
昨天下午CAE的Evan編寫的一個動態庫libcapi_pcie.so中用到了libnative.so。這樣Evan的一個工程下就有了3個動態庫libcapi_pcie.so, libnative.so和libs2cShareLib.so,
他的編譯命令列是這樣的:
"gcc -rdynamic -DKERNEL_64BIT -m64 -DLINUX -Wall -o main main.c -ldl",
並沒有指定連結相關動態庫,而是在程式中採用手動方式載入動態庫:
“void *CAPI_LIB_handle = dlopen(”./capi_pcie.so“, RTLD_LAZY);
......
dlclose(CAPI_LIB_handle);"
編譯完,執行"./main",前面都執行正常,到最後程式退出時出現segment fault。
我們嘗試了幾種改動都可以避免出現segment fault:
1. 註釋掉程式碼最後”(CAPI_LIB_handle);“;
2.註釋掉libnative.so中呼叫libs2cShareLib.so的部分程式碼並重新編譯libnative.so;
問題貌似已經定位到是libs2cShareLib.so的問題了,但這個庫是我寫的,經過反覆測試的,我把自己的測試程式拿到Evan那裡跑也是OK的。難道是動態庫中呼叫動態庫會有什麼限制?我又寫了個自測試程式測試libnative.so。編譯引數:
”gcc -o test -lnative -lstdc++ main.cpp“
結果一切正常。
只能查詢我測試程式和Evan程式的不同了,不同點有兩個:
1.我的測試程式中的呼叫關係是:test->libnative.so->libs2cShareLib.so,兩層動態庫呼叫;而Evan的程式中是main->libcapi_pcie.so->libnative.so->libs2cShareLib.so,三層動態庫呼叫。
2.我的測試程式中我是用連結器連結要用到的動態庫;而Evan的程式中是採用手動load的方式。
一個一個來排查,針對第一點,讓Evan修改他的程式,直接load libnative.so,結果還是出錯,說明不是動態庫呼叫層數的關係了。
針對第二點,修改Evan的編譯選項,指定連結要用到的相關動態庫,而不是程式中手動load。執行,結果正確!!!
說明不是動態庫本身的問題了,難道說多層動態庫呼叫不能手動load?帶著這個疑問找老大,老大看了一下Evan程式碼,指著”void *CAPI_LIB_handle = dlopen(”./capi_pcie.so“, RTLD_LAZY); “這一行,會不會是這個load引數的問題。百度了一下:
果斷把RTLD_LAZY改成RTLD_NOW,重新編譯執行,正常,也沒有segment fault了。
終於找到原因了,RTLD_LAZY在呼叫dlopen時為了節省時間,並沒有解析所用到的未定義符號,而是在用到的時候再來解析;而RTLD_NOW就是解析所有用到的符號,類似於連結器連結指定動態庫的效果。
但還是有個問題搞不明白,問什麼在libnative.so中註釋掉呼叫libs2cShareLib.so的程式碼, RTLD_LAZY方式就是可以的呢?
main->libcapi_pcie.so->libnative.so->libs2cShareLib.so 程式結束出現segment fault錯誤;
main->libcapi_pcie.so->libnative.so 程式結束,正常退出。
希望有大神幫忙解惑,小弟感激不盡!
相關文章
- Linux共享庫、靜態庫、動態庫詳解Linux
- Linux下的共享庫(動態庫)和靜態庫Linux
- Linux下共享庫問題導致無法啟動SQLPLUS的問題解決LinuxSQL
- oracle呼叫C動態庫Oracle
- 動態庫的建立和呼叫
- java動態呼叫c++庫JavaC++
- linuxjna呼叫so動態庫Linux
- java呼叫c++動態庫之jni呼叫JavaC++
- SQLLDR利用EXPRESSION生成LOGFILE的檔名導致SEGMENTATION FAULTSQLExpressSegmentation
- Linux 靜態庫生成及呼叫Linux
- Linux下動態共享庫 連線和載入路徑Linux
- Linux 依賴動態庫 / 靜態庫的動態態庫 / 靜態庫Linux
- C語言動態呼叫庫(轉)C語言
- linux下使用boost.python呼叫c++動態庫LinuxPythonC++
- Linux動態庫Linux
- Linux下的靜態庫、動態庫和動態載入庫Linux
- 資料庫恢復狀態可能導致JOB無法自動執行資料庫
- VS中呼叫DLL動態庫的方法
- linux下的靜態庫與動態庫Linux
- C#呼叫C++動態連結庫C#C++
- C++呼叫C#的動態庫dllC++C#
- 作業系統動態庫呼叫過程作業系統
- SCHEDULER呼叫XDB程式導致效能問題
- ubuntu7下軟體執行出現segment fault錯誤Ubuntu
- linux 動態庫 靜態庫 函式覆蓋Linux函式
- 在Linux中建立靜態庫和動態庫Linux
- linux下動態共享庫的建立,使用與更新(包括ldconfig的使用)Linux
- linux general protection faultLinux
- .net呼叫靜態庫
- EM自動任務導致資料庫緩慢資料庫
- 簡述Linux下的靜態庫和動態庫Linux
- Linux靜態庫和動態庫學習總結Linux
- Linux環境下建立靜態庫和動態庫Linux
- <摘錄>Linux下動態共享庫載入時的搜尋路徑詳解Linux
- java動態呼叫webserviceJavaWeb
- VC動態呼叫DLL
- 導致爬蟲動態代理IP超時的原因有哪些爬蟲
- 動態建立 @ViewChild 導致執行時錯誤的原因分析View