記一次使用 Windows 除錯套件 gflags 解決 CefSharp 載入報錯資訊模糊的問題

發表於2024-02-29

最近寫 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 周邊相關優質技術文,共同進步,一起加油~

相關文章