首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

SystemTap Guru 模式深度解析:嵌入 C 代碼與核心探測實戰

     編輯:關於C

什麼是 Guru 模式?

SystemTap 的 Guru 模式(-g 選項)允許在腳本中直接嵌入 C 代碼,繞過安全檢查,獲得對核心資料結構的完全存取權。嵌入代碼置於 %{ ... %} 標記間,編譯器將其原樣放入生成的核心模組。

嵌入 C 代碼的三種位置

%{
#include 
#include 
%} /* 頂層:引入核心標頭檔 */

function read_iphdr:long(skb:long) %{ /* 函數體:完整 C 函數實作 */
    struct iphdr *iph = ip_hdr((struct sk_buff *)STAP_ARG_skb);
    STAP_RETVALUE = (long)iph;
%}

function is_tcp_packet:long(iphdr) { /* 混合模式:Script 語言 + 嵌入運算式 */
    protocol = @cast(iphdr, "iphdr")->protocol
    return (protocol == %{ IPPROTO_TCP %})  // 嵌入常數運算式
}

參數存取與返回值:版本差異關鍵

項目SystemTap 1.7 及之前SystemTap 1.8+ (含 CentOS 6.4)
參數存取THIS->argnameSTAP_ARG_argname
返回值設定THIS->__retvalueSTAP_RETVALUE

遷移提示:舊腳本升級時必須全域替換上述宏,否則編譯報錯。

安全存取核心指標:kread 宏

Guru 模式下指標解參考可能導致核心崩潰,務必使用 kread 安全讀取:

struct net_device *dev;
char *name;
dev = kread(&(skb->dev));      // 安全讀取 skb->dev
name = kread(&(dev->name));    // 安全讀取 dev->name

中斷上下文限制:絕對不可睡眠

所有 SystemTap 探測處理器與 Guru 函數均在 關閉中斷 的原子上下文執行,嵌入 C 代碼中嚴禁呼叫可能睡眠的函數(如 kmalloc(GFP_KERNEL)、mutex_lock、copy_to_user 等),違者必導致核心死鎖或崩潰。

完整範例:TCP 封包偵測

probe begin { printf("SystemTap start!\n"); }

probe kernel.function("ip_local_deliver") {
    iph = read_iphdr(pointer_arg(1));
    printf("tcp packet ? %s\n", is_tcp_packet(iph) ? "yes" : "no");
}

此範例展示:頂層引入標頭檔 → Guru 函數解析 sk_buff → 混合函數判斷協定 → 探測點掛載核心函數入口。

最佳實踐總結

  1. 優先使用純 Script API,僅在必要時啟用 Guru 模式。
  2. 嵌入 C 代碼前務必確認核心版本相容性(結構體佈局可能變更)。
  3. 所有指標解參考統一用 kread/kwrite。
  4. 嚴禁阻塞式操作,保持執行路徑極短。
  5. 開發階段建議在測試機或虛擬機驗證,避免影響生產環境。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved