(第一版:致力于讓我們研究調試Linux內核代碼不再痛苦) 是獲取任何一個對象,對象的來源可以是動態事件(kprobe_event/uprobe_event) 或者靜態事件(tracepoint)設置的參數,然后跟蹤這個對象穿過的所有函數。
目前到了第四版,演變成首先獲取一個對象,然后動態獲取對象的值,舉一個例子,對于函數bio_add_page():
For the function bio_add_page():int bio_add_page(struct bio *bio, struct page *page,unsigned int len, unsigned int offset)
probe 函數bio_add_page(), 獲取這個函數的第一個參數,這個參數就稱為一個object,這個object就是struct bio的指針。
echo 'p bio_add_page arg1=$arg1' >> ./kprobe_events然后接下來關鍵的一步是,根據以上object, 可以動態輸出這個object結構中某個成員的值:
find the offset of the bi_size in struct bio:$ gdb vmlinux(gdb) p &(((struct bio *)0)->bi_iter.bi_size)$1 = (unsigned int *) 0x28echo 'objtrace:0x28(arg1):u32:1 if comm == "cat"' > ./events/kprobes/ \p_bio_add_page_0/trigger
由于以上輸出到ring buffer的數據會比較多,可以設置起始和結束跟蹤函數:
dd if=/dev/zero of=/test.txt bs=4k count=3cd /sys/kernel/debug/tracing/echo 0 > ./tracing_onecho 'p read_pages' >> ./kprobe_eventsecho 'p blk_account_io_start' >> ./kprobe_eventsecho 'traceon if comm == "cat"' > ./events/kprobes/p_read_pages_0/triggerecho 'traceoff if comm == "cat"' > ./events/kprobes/p_blk_account_io_start_0/triggerecho 'p bio_add_page arg1=$arg1' >> ./kprobe_eventsecho 'objtrace:0x28(arg1):u32:1 if comm == "cat"' > ./events/kprobes/p_bio_add_page_0/triggercat /test.txt > /dev/nullcat ./trace
最后輸出的數據:
可以動態抓到bio->bi_iter.bi_size 值的變化。
cat-95 [000] ..... 1.412065: _raw_spin_unlock_irqrestore <-event_triggers_call object:0xffff888108af6328 value:0x0cat-95 [000] ..... 1.412066: __bio_try_merge_page <-bio_add_page object:0xffff888108af6328 value:0x0cat-95 [000] ..... 1.412066: __bio_add_page <-bio_add_page object:0xffff888108af6328 value:0x0cat-95 [000] ..... 1.412066: rcu_read_unlock_strict <-xa_load object:0xffff888108af6328 value:0x1000cat-95 [000] ..... 1.412066: bio_add_page <-ext4_mpage_readpages object:0xffff888108af6328 value:0x1000cat-95 [000] ..... 1.412066: kprobe_ftrace_handler <-ftrace_ops_list_func object:0xffff888108af6328 value:0x1000cat-95 [000] ..... 1.412067: get_kprobe <-kprobe_ftrace_handler object:0xffff888108af6328 value:0x1000cat-95 [000] ..... 1.412067: __bio_try_merge_page <-bio_add_page object:0xffff888108af6328 value:0x1000cat-95 [000] ..... 1.412067: __bio_add_page <-bio_add_page object:0xffff888108af6328 value:0x1000cat-95 [000] ..... 1.412067: rcu_read_unlock_strict <-xa_load object:0xffff888108af6328 value:0x2000cat-95 [000] ..... 1.412067: bio_add_page <-ext4_mpage_readpages object:0xffff888108af6328 value:0x2000cat-95 [000] ..... 1.412067: kprobe_ftrace_handler <-ftrace_ops_list_func object:0xffff888108af6328 value:0x2000cat-95 [000] ..... 1.412067: get_kprobe <-kprobe_ftrace_handler object:0xffff888108af6328 value:0x2000cat-95 [000] ..... 1.412067: __bio_try_merge_page <-bio_add_page object:0xffff888108af6328 value:0x2000cat-95 [000] ..... 1.412068: submit_bio <-ext4_mpage_readpages object:0xffff888108af6328 value:0x3000cat-95 [000] ..... 1.412068: submit_bio_noacct <-ext4_mpage_readpages object:0xffff888108af6328 value:0x3000....
第四版發過去之后, 由于Linux5.15剛剛發布,進入到了linux5.16的合并窗口,maintainer最近兩周沒有時間review,還專門解釋了一下,nice(+0).

查看[PATCH v4 1/2] trace: Add trace any kernel object
點擊閱讀原文.
我在閱碼場平臺發布過tracing視頻課程,歡迎掃碼訂閱:

---end---