日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

kprobe原理解析

發布時間:2023/12/13 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kprobe原理解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考??http://www.cnblogs.com/honpey/p/4575928.html

?kprobe是linux內核的一個重要特性,是一個輕量級的內核調試工具,同時它又是其他一些更高級的內核調試工具(比如perf和systemtap)的“基礎設施”,4.0版本的內核中,強大的eBPF特性也寄生于kprobe之上,所以kprobe在內核中的地位就可見一斑了。

kprobe是什么?

如何高效地調試內核?printk是一種方法,但是printk終歸是毫無選擇地全量輸出,某些場景下不實用,于是你可以試一下tracepoint,我使能tracepoint機制的時候才輸出。對于傻傻地放置printk來輸出信息的方式,tracepoint是個進步,但是tracepoint只是內核在某些特定行為(比如進程切換)上部署的一些靜態錨點,這些錨點并不一定是你需要的,所以你仍然需要自己部署tracepoint,重新編譯內核。那么kprobe的出現就很有必要了,它可以在運行的內核中動態插入探測點,執行你預定義的操作。

kprobe怎么使用?

kprobe主要有兩種使用方法,一是通過模塊加載;二是通過debugfs接口。

模塊加載的方式:內核源碼下有目錄下 samples/kprobes,該目錄下有許多kprobes的例子,可以仿照這些例子寫自己的kprobe模塊。以kprobe_example.c為例,首先聲明一個kprobe結構體,然后定義其中幾個關鍵成員變量,包括symbol_name,pre_handler,post_handler。其中,symbol_name是函數名(kprobe_example.c中該項為do_fork),告訴內核我的探測點放置在了函數do_fork處,pre_hander和post_hander分別表示在執行探測點之前和之后執行的鉤子函數。然后通過register_kprobe函數注冊kprobe即可。將kprobe_example.ko inmod進內核之后,每當系統新啟動一個進程,比如執行ls,cat等,都會輸出:

????????????? pre_hander: p->addr = 0x***, ip = ****.

????????????? post_handler: p->addr = 0x***, pc = ****.

第一行是執行pre_handler鉤子函數的輸出,第二行是執行post_handler鉤子函數的輸出,當然這些都是內核中案例的寫法,你可以寫自己的鉤子函數。

通過debugfs接口注冊kprobe:模塊加載的終究不是很方便,尤其對于一些不帶gcc的嵌入式系統,需要交叉編譯ko,將ko拷貝到單板,然后insmod,不便。debugfs下(確切地說,應該是ftrace)提供了一套注冊、使能、注銷kprobe的接口,可以很方便地操作kprobe。

用法如下:

  1) cd /sys/kernel/debug/tracing【有些系統沒有掛載debugfs,需要先掛載下 mount -t debugfs nodev /sys/kernel/debug】

  2)進入到tracing目錄,這里就是傳說中ftrace的天下了,執行:

echo "p:sys_write_event sys_write" > kprobe_events

向kprobe_events寫入"p:sys_write sys_write",注冊kprobe事件。你會發現,當前目錄下的events下,新增一個kprobes目錄,該目錄下:

root@station:/sys/kernel/debug/tracing/events/kprobes# lsenable filter sys_write_event

即,我們注冊的kprobe事件生效了。那么"p:sys_write_event sys_write"是什么意思呢?首先p表示我們要注冊一個kprobe,如果要注冊retprobe,此處應為r;sys_write_event表示這個kprobe叫什么名字;sys_write表示我們的插入點在哪里。那么,“p:sys_write_event sys_write”的語義就很明顯了:在函數sys_write處插入一個kprobe點,這個點的名字叫sys_write_event。

????? 3)使能kprobe。執行:

cd /sys/kernel/debug/tracing/events/kprobes/events/sys_write_event echo 1 > enable cd ../../.. 【退回到/sys/kernel/debug/tracing,查看trace文件的輸出】 cat trace trace文件的輸出是如下的:.....bash-808 [003] d... 42715.347565: sys_write_event: (SyS_write+0x0/0xb0) ? ?解釋下置紅的這條輸出:pid為808的進程bash,在自本次開機42715.345565秒的時候,調用了一次函數sys_write。.....

? 4)撤消kprobe。執行:

cd /sys/kernel/debug/tracing/events/kprobes/events/sys_write_event echo 0 > enable【首先先關閉kprobe】 cd ../../.. echo "-:kprobes/sys_write_event" >> kprobe_events 【注銷kprobe】

以上就是kprobe的兩種注冊及使用方式:通過模塊加載以及通過debugfs注冊。這兩種使用方法有什么聯系?

使用模塊加載的方式,是kprobe的一種原始用法:在kprobe結構體里定義插入點、鉤子函數,然后通過register_kprobe注冊上這個kprobe即可。ftrace接口是kprobe的一種應用,它是一套trace的框架,下面的trace機制包括tracepoint、function trace等,kprobe僅僅是這些trace機制中的一員。上面的講述我們也已經看出來了,通過ftrace注冊的kprobe的輸出是在ftrace的輸出:trace文件。模塊加載模式中我們可以自定義kprobe的鉤子函數pre_handler和post_handler,但是在ftrace下注冊的kprobe的鉤子是ftrace接口默認的,我們設置不了,但是具體輸出什么,我們可以在echo “p:sys_write_event sys_write"時指定,比如指定x1寄存器的內容等,所以ftrace下注冊的kprobe功能同樣很強大。同時,由于ftrace下kprobe的輸出基于ftrace的輸出框架,所以輸出信息包含當前進程、CPU、時間戳等信息,對于trace來說非常有用。

高級用法可以參看內核文檔:kprobes.txt 以及 kprobetrace.txt。

?

轉載于:https://www.cnblogs.com/xingmuxin/p/8984043.html

總結

以上是生活随笔為你收集整理的kprobe原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。