GDB 除錯 .NET 程式實錄 - .NET 呼叫 .so 出現問題怎麼解決
客戶給了一些 C語言 寫的 SDK 庫,這些庫打包成 .so 檔案,然後我們使用 C# 呼叫這些庫,其中有一個函式是回撥函式,引數是結構體,結構體的成員是函式,將 C# 的函式賦值給委託,然後儲存到這個委託中。
C# 呼叫 C 語言的函式,然後 C 語言執行到一些步驟後, C 語言函式呼叫 C# 的函式。這個在 ARM64 的機器下,是正常的,例如樹莓派,華為的鯤鵬伺服器等。由於突然改成使用 X64 的機器部署專案,沒有測試就直接打包了(Docker)。
沒有測試的原因有兩個:一是,眾所周知 .NET Core 是跨平臺的,既然在 ARM64 下已經測試過,那麼應該沒問題;
二是,專案是華為 edge IoT 專案,必須走華為雲註冊邊緣裝置,然後通過雲服務下發應用(Docker)到機器才能成功執行(有許多系統自動建立的環境變數和裝置連線華為 IoT 的憑證)。在機器上直接啟動,是無法正常完成整個流程的。
三是,事情來得太突然,沒有時間測試。
事實上,就是這麼幸福,出事的時候就是加班福報~~~ 大家記得,要部署上線、演示專案之前,一定要測試,測試再測試。 ### 出現問題 應用在雲上下發到裝置後,啟動一會兒就會掛了,然後修改 Docker 容器的啟動指令碼,進入容器後,手動執行命令啟動程式。 最後發現: ```shell dotnet xxx.dll ... ... Segmentation fault (core dumped) ``` 出現這個 `Segmentation fault (core dumped)` 問題可能是指標地址越界、訪問不存在的記憶體、記憶體受保護等,參考: http://ilinuxkernel.com/?p=1388 https://www.geeksforgeeks.org/core-dump-segmentation-fault-c-cpp/ 由於這個問題是核心級別的,所以可以從系統日誌中找到詳細的日誌資訊。 ### 檢視 核心日誌 容器和物理機都可以檢視日誌,但是容器裡面的資訊太少,主要從物理機找到資訊的日誌。 在物理機: ```shell # 核心日誌 cat /var/log/kern.log ``` ![kern日誌](https://img2020.cnblogs.com/blog/1315495/202010/1315495-20201012181913785-1569076048.png) ```powershell # 系統日誌 cat /var/log/syslog ``` 剛開始時,大佬提示可能是記憶體已被回收,函式等沒有使用靜態來避免 gc 回收,可能在 C 回撥之前,C# 中的那部分記憶體就以及回收了。 但是我修改程式碼,都改成靜態,並且列印地址,還禁止 GC 回收,結果還是一樣的。 檢視引用型別在記憶體中的地址 : ```csharp public string getMemory(object o) { GCHandle h = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection); IntPtr addr = GCHandle.ToIntPtr(h); return "0x" + addr.ToString("X"); } ``` 禁止 GC 回收: ```csharp GC.TryStartNoGCRegion(1); ... ... GC.EndNoGCRegion(); ``` ### 工具除錯 經過提示,知道可以使用 GDB 除錯 .so,於是馬上 Google 查詢資料,經過一段時間後,學會了使用這些工具查詢異常堆疊資訊。 #### GDB GNU Debugger,也稱為 **gdb,**是用於 UNIX系統除錯 C 和 C ++ 程式的最流行的偵錯程式。If a core dump happened, then what statement or expression did the program crash on?
If an error occurs while executing a function, what line of the program contains the call to that function, and what are the parameters?
What are the values of program variables at a particular point during execution of the program?
What is the result of a particular expression in a program?
Jexus 是強勁、堅固、免費、易用的國產 WEB 伺服器系統,可替代 Nginx 。Jexus 支援 Arm32/64、X86/X64、MIPS、龍芯等型別的 CPU,是一款Linux平臺上的高效能WEB伺服器和負載均衡閘道器伺服器,以支援ASP.NET、ASP.NET CORE、PHP為特色,同時具備反向代理、入侵檢測等重要功能。
可以這樣說,Jexus是.NET、.NET CORE跨平臺的最優秀的宿主伺服器,如果我們認為它是Linux平臺的IIS,這並不為過,因為,Jexus不但非常快,而且擁有IIS和其它Web伺服器所不具備的高度的安全性。同時,Jexus Web Server 是完全由中國人自主開發的的國產軟體,真正做到了“安全、可靠、可控”, 具備我國黨政機關和重要企事業單位資訊化建設所需要的關鍵品質。