Linux-Kernel

如何分析在使用者模式和核心模式下進行的虛擬記憶體訪問?

  • August 17, 2021

由於執行某些程序,我想生成在使用者模式和核心模式下執行的所有虛擬記憶體訪問的日誌。

除了收集記憶體訪問位置之外,我還想擷取其他狀態資訊(例如,指令指針、執行緒標識符)。我預計我將無法使用任何開箱即用的工具收集我想要的所有統計數據。

我打算離線進行此分析,因此我不擔心性能影響。事實上,根據可用的工具,了解哪些工具可以記錄所有記憶體訪問以及哪些工具只能進行採樣會很有幫助。

我最初打算擴充 Valgrind 的缺乏工具,直到我意識到它只記錄使用者模式的記憶體訪問。查看我可能使用的其他工具,我不知道如何快速確定哪種工具能夠擷取我想要的資訊。

以下是我發現的一些讓我開始的資源:

我想用我找到的資訊更新我的問題,以防其他人有類似的問題。

我對 Linux 跟踪工具的理解是,大多數使用探針(我用來描述動態插入執行檔的二進製文件的工具)和跟踪點(我用來描述編譯成可以啟用或禁用的程式碼的工具)跟踪大規模的事件(例如,函式呼叫)。因此,這些工具對於跟踪像記憶體訪問這樣細粒度的東西沒有幫助。

Valgrind 對於跟踪使用者程式碼(但不是核心程式碼,因為它在合成 CPU 上執行程序)進行的所有記憶體訪問非常有用。從文件:

然後,您的程序將在 Valgrind 核心提供的合成 CPU 上執行。當新程式碼第一次執行時,核心將程式碼交給選定的工具。該工具將其自己的檢測程式碼添加到其中並將結果返回給核心,該核心協調該檢測程式碼的繼續執行。

這似乎表明需要在傳遞要執行的每條指令的組件級別收集此類跟踪資訊。因此,在不使用模擬器的情況下,似乎沒有一種方法可以在執行使用者和核心程式碼時獲得這種深度和廣度的資訊。

這使我想到了我找到的唯一解決方案:perf_event_open(). 它可以使用處理器的性能監控單元 (PMU) 對記憶體訪問進行採樣。perf_event_open()可以提供足夠深度的資訊(例如,指令指針、記憶體地址、程序寄存器)但不能提供廣度(因為它只能對記憶體訪問進行採樣)。

(此外,perf mem前端是開始收集有關記憶體訪問的此類資訊的好且容易的地方。然後可以使用離線處理樣本perf script。)

引用自:https://unix.stackexchange.com/questions/658075