文章目錄
- 0.問題背景
- 1.程序啟動失敗常見原因
- 2.排查依賴庫問題
- 2.1 依賴庫缺失
- 2.2 依賴庫加載路徑錯誤
- 2.3 依賴庫版本不匹配
- 2.4 QT插件庫缺失
- 2.4.1 QT插件庫缺失
- 2.4.2 插件庫自身的依賴庫缺失
- 2.5 系統基礎C庫不匹配
- 3.資源問題
- 3.1 缺少翻譯文件
- 3.2 缺少依賴的資源文件
- 3.3 缺少依賴的可執行程序
- 4.程序權限問題
- 5.運行崩潰問題
0.問題背景
在當前的主流開發語言中Java和web都有成熟的包依賴管理工具,能夠輕松的管理程序依賴,然而C++目前僅僅只有像vcpkg和conan這樣的開源庫構建工具,并沒有程序依賴庫管理工具。在Linux系統軟硬件如此豐富的今天,想一個C++程序能夠兼容多個操作系統,是一件很有挑戰的事情。下面文章中將要講到的是平時在實踐過程中遇到的一些問題的總結分享,希望能給讀者一些啟發。
1.程序啟動失敗常見原因
Linux下程序啟動失敗的原因主要有幾個原因,下面將從每個原因進行具體的分析。
2.排查依賴庫問題
2.1 依賴庫缺失
通過ldd命令查看依賴庫問題的正確步驟,第一步先確認可執行程序的依賴庫是否缺失,如果缺失查看缺失依賴庫自身的依賴庫是否正常,通過一層層查詢,基本能定位缺失的依賴庫問題。
#查看可執行程序依賴庫示例
ldd -d example#查看動態庫的依賴庫
ldd -d libQt5Gui.so
依賴庫缺失示例:
2.2 依賴庫加載路徑錯誤
因為windows和Linux系統機制的問題,Linux默認從系統路徑加載動態庫,這導致程序啟動時加載的不是當前路徑下的動態庫,如果版本不匹配就會出現程序啟動失敗。解決這個問題的辦法有兩個:1.編譯動態庫時指定需要鏈接動態庫的相對路徑;2.通過pathelf命令修改動態庫的運行時路徑。
2.3 依賴庫版本不匹配
依賴庫版本不匹配的情況一般有兩種情況,第一種動態庫編譯環境編譯時依賴的動態庫版本和運行環境中依賴的庫版本不同,這就導致運行時庫版本不匹配,最常見的問題像libicui18n.so、libicudata.so、libssl等。
2.4 QT插件庫缺失
QT自帶插件是在使用特定模塊時必須依賴的動態庫,在發布程序時必須一起發布,但是因為我們在開發階段因為開發環境的的問題很容易忽視這個問題,導致在純凈環境部署時出現程序因為缺少必須的插件庫而無法運行。
2.4.1 QT插件庫缺失
解決QT插件庫缺失的兩種方法,第一種利用經驗根據自己使用到的板塊拷貝對應的插件到發布目錄;第二種方法利用開源工具linuxdeployqt自動拷貝所有依賴的Qt環境到發布目錄。
2.4.2 插件庫自身的依賴庫缺失
QT插件庫很多是依賴系統庫的,比較典型的是libqxcb.so依賴libxcb-xinput.so,很多系統沒有這個依賴環境,因此在打包時我們需要將這個系統依賴庫放到我們發布目錄進行一起發布。
2.5 系統基礎C庫不匹配
當我們使用高版本的gcc編譯器編譯程序在低版本的gcc系統中運行時很容易出現C庫找不到的問題,主要是因為使用高版本gcc進行編譯時會引入高版本c庫的函數,而在低gcc環境上是沒有這些函數的,這就導致程序找不到依賴的c庫的接口而無法啟動。
3.資源問題
3.1 缺少翻譯文件
Qt的QWebEngine模塊強依賴翻譯文件,在缺失翻譯文件時程序直接啟動失敗。解決辦法需要將QT安裝目錄下的translations文件夾放到發布目錄的根目錄,尤其是其中的qtwebengine_locales文件夾一定不能少。
3.2 缺少依賴的資源文件
Qt的QWebEngine模塊強依賴翻譯資源文件,在缺失資源文件時程序直接啟動失敗。解決辦法是將QT安裝目錄下的resources文件夾放到發布目錄的根目錄。
3.3 缺少依賴的可執行程序
Qt的QWebEngine模塊依賴QtWebEngineProcess進程和qwebengine_convert_dict可執行程序,缺少這兩個文件程序將無法啟動。QtWebEngineProcess是chromium內核的獨立進程,為了避免chromium內核崩潰導致主進程崩潰QT設計人員將其獨立成了一個單獨的進程,所以這個在做嵌入網頁的功能時是必不可少的。
4.程序權限問題
權限問題是linux下非常常見的問題,主要有兩種操作可能出現權限問題,第一種我們的軟件安裝是是非root權限安裝的軟件,第二種是我們替換軟件目錄的可執行程序導致可執行無運行權限。對于第一種我們只能卸載重裝使用有root權限的賬號進行安裝,第二種情況我們可以使用chmod命令修改權限即可。
5.運行崩潰問題
程序啟動運行崩潰看起來像程序運行不起來,這是程序本身代碼的問題,有兩種方法可以進行排查。第一種拿到程序崩潰生成的core文件使用gdb查看調用棧進行分析,第二種通過strace命令啟動應用程序,可以查看詳細的程序加載過程。