(第一版:致力于让我们研究调试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 *) 0x28
echo '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=3
cd /sys/kernel/debug/tracing/
echo 0 > ./tracing_on
echo 'p read_pages' >> ./kprobe_events
echo 'p blk_account_io_start' >> ./kprobe_events
echo 'traceon if comm == "cat"' > ./events/kprobes/p_read_pages_0/trigger
echo 'traceoff if comm == "cat"' > ./events/kprobes/p_blk_account_io_start_0/trigger
echo 'p bio_add_page arg1=$arg1' >> ./kprobe_events
echo 'objtrace:0x28(arg1):u32:1 if comm == "cat"' > ./events/kprobes/p_bio_add_page_0/trigger
cat /test.txt > /dev/null
cat ./trace
最后输出的数据:
可以动态抓到bio->bi_iter.bi_size 值的变化。
cat-95 [000] ..... 1.412065: _raw_spin_unlock_irqrestore <-event_triggers_call object:0xffff888108af6328 value:0x0
cat-95 [000] ..... 1.412066: __bio_try_merge_page <-bio_add_page object:0xffff888108af6328 value:0x0
cat-95 [000] ..... 1.412066: __bio_add_page <-bio_add_page object:0xffff888108af6328 value:0x0
cat-95 [000] ..... 1.412066: rcu_read_unlock_strict <-xa_load object:0xffff888108af6328 value:0x1000
cat-95 [000] ..... 1.412066: bio_add_page <-ext4_mpage_readpages object:0xffff888108af6328 value:0x1000
cat-95 [000] ..... 1.412066: kprobe_ftrace_handler <-ftrace_ops_list_func object:0xffff888108af6328 value:0x1000
cat-95 [000] ..... 1.412067: get_kprobe <-kprobe_ftrace_handler object:0xffff888108af6328 value:0x1000
cat-95 [000] ..... 1.412067: __bio_try_merge_page <-bio_add_page object:0xffff888108af6328 value:0x1000
cat-95 [000] ..... 1.412067: __bio_add_page <-bio_add_page object:0xffff888108af6328 value:0x1000
cat-95 [000] ..... 1.412067: rcu_read_unlock_strict <-xa_load object:0xffff888108af6328 value:0x2000
cat-95 [000] ..... 1.412067: bio_add_page <-ext4_mpage_readpages object:0xffff888108af6328 value:0x2000
cat-95 [000] ..... 1.412067: kprobe_ftrace_handler <-ftrace_ops_list_func object:0xffff888108af6328 value:0x2000
cat-95 [000] ..... 1.412067: get_kprobe <-kprobe_ftrace_handler object:0xffff888108af6328 value:0x2000
cat-95 [000] ..... 1.412067: __bio_try_merge_page <-bio_add_page object:0xffff888108af6328 value:0x2000
cat-95 [000] ..... 1.412068: submit_bio <-ext4_mpage_readpages object:0xffff888108af6328 value:0x3000
cat-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---