QNX system architecture -- Chapter 4:The Instrumented Microkernel

微內核(procnto-instr)的檢測版本配備了複雜的跟蹤和分析機制,可讓您實時監控系統的執行情況。procnto-instr模塊適用於單CPU和SMP系統。

procnto-instr 模塊使用非常少的開銷並且提供了非常好的性能 - 它通常比非器械內核(當它不記錄時)快98%。儀表內核中額外的代碼量(x86系統上大約30 KB)對於這個有用工具的附加功能和靈活性來說是一個相對較小的代價。根據最終系統的佔地面積要求,您可以選擇將此特殊內核用作開發/原型設計工具或最終產品中的實際內核。

檢測模塊是非侵入式的 - 您不必修改程序的源代碼以監視程序與內核的交互方式。 您可以根據需要在內核與系統中任何正在運行的線程或進程之間跟蹤多個或幾個交互(例如,內核調用,狀態更改和其他系統活動)。你甚至可以監控中斷。在這種情況下,所有這些活動都稱爲事件。

Instrumentation at a glance

以下是內核檢測中涉及的基本任務:

  1. 由於各種系統活動,微內核(procnto-instr)會發出跟蹤事件。這些事件會自動複製到一組分組爲循環鏈表的緩衝區中。

  2. 一旦緩衝區內的事件數達到高水位線,內核就會通知數據捕獲實用程序。

  3. 數據捕獲程序,然後寫入從所述緩衝器中的跟蹤事件到輸出裝置(例如,一個串行端口,一個事件文件,等)。

  4. 數據解讀機構隨後解釋事件,並提出這些數據給用戶。

Event control

鑑於在實時系統中發生的大量活動,內核發出的事件數量可能是巨大的(就數據量,處理要求和存儲它所需的資源而言)。 但您可以輕鬆控制發出的數據量。

具體來說,您可以:

•控制觸發事件發射的初始條件
•應用預定義的內核過濾器來動態控制排放
•實現自己的事件處理程序以進行更多過濾。

數據捕獲實用程序(tracelogger)收集數據後,即可對其進行分析。您可以在收集相關事件後實時或離線分析數據。IDE中的系統分析工具以圖形方式顯示此數據,以便您“查看”系統中發生的情況。

Modes of emission

除了應用各種過濾器來控制事件流之外,您還可以指定內核可用於發出事件的兩種模式之一:

這裏的權衡是速度與知識之間的關係:快速模式提供的數據較少,而寬模式爲每個事件包含更多信息。無論哪種方式,您都可以輕鬆調整系統,因爲這些模式基於每個事件。

作爲快速和寬發射模式之間差異的一個例子,讓我們看看我們可能看到的MsgSendv()調用條目的信息種類:

Ring buffer

內核可以將所有跟蹤事件保存在內部循環緩衝區中,而不是始終向外部設備發送事件。

當滿足某個觸發條件時,可以按需編程將此緩衝區轉儲到外部設備,這使得它成爲識別在某些運行時條件下出現的難以捉摸的錯誤的非常強大的工具。

Data interpretation

event數據包括高精度時間戳以及生成event的CPU的ID號。此信息可幫助您輕鬆診斷困難的計時問題,這些問題更可能發生在多處理器系統上。

事件格式還包括CPU平臺(例如,x86,ARM等)和endian類型,這有助於遠程分析(無論是實時還是離線)。使用數據解釋器,您可以通過各種方式查看數據輸出,例如:

•基於時間戳的整個系統的線性表示
•僅活動線程/進程的“運行”視圖
•每個進程/線程的事件的基於狀態的視圖。
數據解釋器的線性輸出可能如下所示:

爲了幫助您微調對事件數據流的解釋,我們提供了一個庫(traceparser),您可以編寫自己的自定義事件解釋器。

System analysis with the IDE

System Analysis Toolkit(SAT)的IDE模塊可用作綜合儀器控制和後處理可視化工具。

在IDE中,開發人員可以配置所有跟蹤事件和模式,然後自動將日誌文件傳輸到遠程系統進行分析。作爲可視化工具,IDE提供了一組豐富的事件和流程過濾器,旨在幫助開發人員快速刪除大量事件集,以便僅查看感興趣的事件。

Proactive tracing

雖然檢測內核爲儀器和監視進程,線程以及系統狀態提供了極好的不顯眼方法,但您也可以讓應用程序主動影響事件收集過程。

使用TraceEvent()庫調用,應用程序本身可以將自定義事件注入跟蹤流。 在構建大型,緊密耦合的多組件系統時,此功能特別有用。
例如,以下簡單調用會將事件代碼的整數值(第一個和第二個)注入事件流:

您還可以將一個字符串(例如,“我的事件”)注入事件流,如以下代碼所示:

#include <stdio.h>
#include <sys/trace.h>
/* Code to associate with emitted events */
#define MYEVENTCODE 12
int main(int argc, char **argv) {
printf("My pid is %d \n", getpid());
/* Inject two integer events (26, 1975) */
TraceEvent(_NTO_TRACE_INSERTSUSEREVENT, MYEVENTCODE,
26, 1975);
/* Inject a string event (My Event) */
TraceEvent(_NTO_TRACE_INSERTUSRSTREVENT, MYEVENTCODE,
"My Event");
return 0;
}

由traceprinter數據解釋器收集的輸出看起來像這樣:

源文件:《The Instrumented Microkernel》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章