如何訪問linux內核,讀取所有進程的task_struct結構?/dev/mem?還是編寫驅動程序?

目的是想通過一個外部工具或者自己編寫一個工具,觀察linux內核?task_struct,mm_struct,vma_area_struct等結構。


推薦crash utility, https://people.redhat.com/anderson/crash_whitepaper/.

Crash 不僅可以實時在線查當前內核的各種數據結構,也可以對memory snapshot查詢。前者可能需要重新編譯內核。

比如命令

task_struct 0xc042c000

顯示地址為0xc042c000的task_struct的內容。這樣你就能得到mm_struct的地址,得到地址後用同樣的方法查詢mm_struct的內容。如此下去,就可以得到你想要的內核數據結構。

Crash基於gdb,所以gdb的命令也都可以用。


現有工具的話 KGTP就可以 KGTP

可以直接訪問 也可以trace某個點的狀態

自己寫可以參考 Hui Zhu: [RFC 4/4] BloodTest: task

對task結構的訪問


@顧宇飛 的答案是正確的,不知為什麼沒有人贊。

我以前也想過這個問題,能否在內核態導出一些sysfs介面,將所有數據結構通過指針鏈起來,但想了一下非常複雜。

後面研究kdump時才發現,內核會提供一個運行時數據的core文件(位於/proc/vmcore還是/proc/kcore),然後使用crash工具就可以查看數據了,當然也可以使用gdb,但是gdb還需要加一個腳本才能認識內存的數據結構。

crash是專門為內核開發的分析工具,它能認識內核通用數據結構。可以使用命令輸出,所以task_struct,所有slub實例,每個slub實例分配出去的空間列表,非常好用的。


班門弄斧+強答預警

操作系統課上寫過一個內核模塊,是簡單的讀取task_struct鏈表的內容,然後輸出到文件。然後用戶態less一下就可以看到信息了。

內核模塊編程的基礎不贅述了,我也不是很熟,總之就是在內核模塊啟動函數裡面用kthread_run開一條內核線程,線程中定時使用內核提供好的宏來遍歷task_struct鏈表,核心代碼是這樣的

struct task_struct* p; //進程句柄指針

rcu_read_lock(); //獲取讀鎖,不知道需不需要,反正我寫了
list_for_each_entry_rcu(p, init_task.tasks, tasks)
{ //內核源代碼頭文件提供的宏,用於遍歷所有進程
//這裡可以使用p來獲取當前遍歷的task_struct的域
}
rcu_read_unlock(); //釋放讀鎖,不知道需不需要,反正我寫了


第一個問題,從用戶態不能直接看到,但是對應的信息是可以查到的 /proc/{pid}/下面就是.

第二個問題,/dev/mem真的是內存,不是虛擬內存.

第三個問題,肯定可以...,把task表遍歷列印一遍就好了.


理解成用戶態與內核太交互,我知道的有3種 但都需要寫個內核模塊:

netlink sock

sysfs

syscall


推薦閱讀:

為什麼 Linux 不用微內核?
在做完內核裁剪後,等待編譯結果的過程是一種怎樣的體驗?
你為什麼學習 Linux 內核?
多個socket同時發送數據,網卡是輪流發送每個socket數據包嗎?每個包多大?

TAG:操作系統 | Linux | 驅動程序 | Linux內核 |