偵錯Go C 共用程式庫問題:網路呼叫掛起
問題
Go 程式在呼叫http.Post() 時遇到掛起同時建構為C 共享庫(-buildmode=c-shared)。但是,標準可執行二進位檔案 (GOOS=linux GOARCH=amd64 ./example) 傳回正確的值。
問題根源
問題的出現是因為在 C 語言時加載了 Go 運行時共享庫由父進程加載。但是,當在分叉子進程中使用該庫時,Go 運行時無法正確加載,從而導致不可預測的行為和掛起調用。
偵錯步驟
-
檢查使用 strace 進行系統呼叫: strace 工具可以顯示正在進行的系統呼叫。例如,執行 strace -fp PID 可能會顯示對 futex 和 Post 操作的調用,例如 futex(0x7f618b2c1cd0, FUTEX_WAKE, 1) 和 Post()。
-
向 HTTP 伺服器新增分析: 要收集有關程式掛起時的狀態信息,請使用 http.ListenAndServe("localhost:6060", nil) 將分析新增至 HTTP 伺服器。這將在連接埠 6060 上執行分析器,可以檢查該分析器以確定掛起的原因。
解決方案
解決方案涉及控制子進程中 Go 運行時的載入過程。為此:
- 在子進程 fork 後使用 dlopen 載入 Go 共享庫。
- 在子進程中使用 dlsym 存取 Go 函式庫中的符號。
透過在子進程中明確載入Go運行時,保證運行時正確初始化並成功進行網路呼叫。
以上是## 為什麼我的 Go C 共享庫在分叉子進程中的網路呼叫上掛起?的詳細內容。更多資訊請關注PHP中文網其他相關文章!