本文回答有關在 .NET 中收集傾印的常見問題。
為什麼 Linux 上的轉儲收集失敗?
為了實作傾印收集,.NET 進程會產生稱為 createdump 的子進程。 此子處理程序使用 Linux API ptrace() ,也從 /proc 檔案系統讀取,以存取寫入傾印檔的執行緒及記憶體資料。 雖然許多 Linux 發行版的預設安全性設定都允許使用 API,但有時不太常見的安全性設定會拒絕存取。 您可能會看到在傾印應用程式主控台上寫入的 createdump 處理程序的輸出,例如:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
可以拒絕訪問的一個原因是,如果安全沙箱使用 seccomp BPF 過濾器攔截呼叫。 對於使用 Open Container Initiative 技術的容器中執行的應用程式,設定檔 seccomp 必須允許呼叫 ptrace。 例如, Docker 在幕後使用 containerd 作為容器執行階段。 初始化時,它會指定預設的 seccomp 設定檔,只有在容器主機的核心版本高於 4.8 或CAP_SYS_PTRACE容器上指定功能時才允許ptrace。
如果呼叫未被攔截,則核心會執行各種內建存取檢查。 ptrace() 的文件在接近結尾的地方包含詳細的描述,標題為“Ptrace 訪問模式檢查”,描述瞭如何完成這些操作。 存取 /proc 檔案系統也會使用相同 ptrace 存取模式檢查的變體。 以下是所執行安全檢查的簡要摘要,以及可能拒絕存取的位置:
- 呼叫處理程序需要具有與目標處理程序相同的使用者 ID,或呼叫處理程序需要具有CAP_SYS_PTRACE。 如果兩者都不成立,則會拒絕存取。 由於 .NET 執行階段在啟動 createdump 時不會執行任何動作來變更使用者帳戶,因此使用者識別碼應該相符,且此步驟應該會成功。
- 如果 createdump 沒有CAP_SYS_PTRACE (預設沒有),則需要將傾印的目標進程標示為「可傾印」。 預設情況下,Linux 上的大多數進程都是可轉儲的,但您可以透過使用 PR_SET_DUMPABLE 選項呼叫 prctl() 來變更此設定。 如果您使用 setcap 工具將功能新增至處理程序,這也可能導致處理程序停止可傾出。 如需可傾印設定的更詳細說明,以及導致停用它的原因,請參閱 Linux 文件。
- 所有已啟用的 Linux 安全模組 (LSM) 都會列舉,而且每一個模組都必須核准存取。 不幸的是,如果 LSM 拒絕訪問,則沒有統一的 Linux 報告機制來了解誰負責。 相反地,您需要判斷系統上啟用了哪些,然後個別調查每一個。 您可以執行以下
cat /sys/kernel/security/lsm命令來判斷哪些 LSM 處於作用中狀態: 。 儘管任何 LSM 都可能負責,但 Yama、 SELinux 和 AppArmor 通常是相關的。
AppArmor 和 SELinux 都有豐富的配置和報告機制,因此如果您需要學習如何使用它們,最好查看每個專案自己的文件。 Yama只有一個配置設置,可以通過運行來顯示:
cat /proc/sys/kernel/yama/ptrace_scope
此指令會輸出一個數字,指出現行 Yama ptrace 安全原則:
- 0:傳統 ptrace 權限。
- 1:受限的 ptrace。
- 2:僅限管理員附加。
- 3:無附加。
Yama 應該在原則 0 和 1 下授與 createdump 的存取權,但預期會在原則 2 和 3 下拒絕存取。 原則 3 一律會拒絕存取,而原則 2 預設不會運作,因為 createdump 通常沒有功能CAP_SYS_PTRACE。
為什麼只有在 dotnet-dump 或我的當機進程以提高許可權的方式執行時,我才會在 Linux 上取得傾印?
部分 Linux 型系統配置了安全策略,這些策略需要任何收集傾出的進程具有CAP_SYS_PTRACE功能。 通常進程沒有此功能,但執行提升許可權是啟用此功能的一種方式。 如需 Linux 安全性原則如何影響傾印收集的完整說明,請參閱 '為什麼 Linux 上的傾印收集失敗?'。
為什麼在容器內運行時無法收集轉儲?
對於在任何 Open Container Initiative 技術下執行的應用程式,設定檔seccomp必須允許呼叫 ptrace()。 例如, Docker 在幕後使用 containerd 作為容器執行階段。 初始化執行階段時,它會指定預設的 seccomp 設定檔,只有在容器主機的核心版本高於 4.8 或CAP_SYS_PTRACE指定功能時才允許ptrace。
如需 Linux 安全性原則如何影響傾印收集的更完整描述,請參閱問題「為什麼 Linux 上的傾印收集失敗?」。
為什麼我無法在 macOS 上收集轉儲?
在 macOS 上,使用 需要 ptrace 目標處理程序的主機獲得適當的授權。 如需最低必要權利的相關資訊,請參閱 預設權利。
哪裡可以深入瞭解如何利用傾印來協助診斷 .NET 應用程式中的問題?
以下是一些其他資源:
如何解決「無法找到任何相容的框架版本」
在 Linux 上,設定時環境 DOTNET_ROOT 變數必須指向正確的資料夾。 當它指向另一個 .NET 版本時, dotnet-dump 一律會產生此錯誤。 未設定環境變數時 DOTNET_ROOT ,會產生不同的錯誤 (「您必須安裝 .NET 才能執行此應用程式」)。