最近寫 CPP 專案遇到了一個問題,用了幾個工具來解決,這裡記錄一下,和大家一起討論。
1. 起因
我的一個 CPP 專案的 UI 框架使用的是 CefSharp,UI 層是 C#,而一些模組程式碼使用的是 CPP,執行報錯如下
報錯資訊是
System.IO.FileLoadException:"未能加由"CefSharp.Core.Runtime.dl"匯入的過程
第一感覺是程式載入某個配置檔案或 dll 未成功,或者動態庫版本問題,但錯報不出來,而且 VS 的 Debugger 無法顯示更多內容,用 Dependencies 看程式,dll 都是找到了的,那會是什麼原因呢?
2. 分析
經過同事的提示,使用微軟提供的 Windows Debugging Tools 除錯套件 gflags.exe
工具,讓程式載入過程中的日誌能在 VS 的<輸出>報出來,配置如下。在 Image File
中輸入完整程式名,然後選中 Show loader snaps 顯示載入器快照,然後重啟程式。
然後重新執行,在 VS 的輸出中就可以看到程式載入過程中的日誌,如下。
在輸出中搜 ERROR,可以看到載入哪些 dll 失敗、警告等資訊,有一些不重要,繼續找發現載入的一個 dbghelp.dll 檔案後,使用它的一個函式 SymGetSearchPathW
未找到失敗,到庫目錄發現這個檔案的時間比較老了,這個方法需要在 6.3 以上版本的 dbghelp.dll 檔案才提供。
可以使用 dumpbin 命令的 dumpbin dbghelp.dll /EXPORTS
命令看到這個 dll 裡並沒有這個SymGetSearchPathW
方法,如下
也可以使用 Dependencies 這個工具來看 dll 中的入口函式,如下
3. 解決
將專案的庫目錄里老版本 dbghelp.dll 刪掉,讓程式去系統的庫目錄裡找較新的 dll,然後執行成功。
4. 覆盤
對於程式(也就是 Image File),gflags.exe
的 Show loader snaps 選項開啟之後會允許捕獲載入和解除安裝 dll 的資訊,並在偵錯程式控制檯中顯示這些資訊,如果過程中有報錯資訊也可以一併展示,所以可以用來查詢類似於載入解除安裝動態庫報錯的問題。這個工具還可以做很多事情,監控記憶體分配、檢查記憶體洩露等等,非常實用,後面再找個時間學習一下。
Windows 上的 dumpbin
命令和 linux 下的 ldd
命令,是用來檢視動態庫資訊的,包括可執行檔案和動態連結庫檔案的依賴項。dumpbin
命令可以用來看動態庫匯出了哪些函式 dumpbin /EXPORTS a.dll
,exe 載入了哪些動態庫 dumpbin /IMPORTS a.exe
,檢視靜態連結庫中包含哪些函式 dumpbin /ALL /RAWDATA:none a.lib
。另外,這個命令預設是不在 cmd 裡,安裝了 VS 的話需要在 VS 的開發者命令提示 Developer Command Prompt 裡執行才能找到這個命令。
網上的帖子大多深淺不一,甚至有些前後矛盾,在下的文章都是學習過程中的總結,如果發現錯誤,歡迎留言指出,如果本文幫助到了你,別忘了點贊支援一下哦,你的點贊是我更新的最大動力!~
PS:本文同步更新於在下部落格 Github - SHERlocked93/blog 系列文章中,歡迎大家關注我的公眾號 CPP下午茶
,直接搜尋即可新增,持續為大家推送 CPP 以及 CPP 周邊相關優質技術文,共同進步,一起加油~