【Ftrace 专栏】Ftrace 基础使用
Ftrace 基础使用
文章目录
- Ftrace 基础使用
- 1、查看函数被执行
- 2、查看模块的执行函数
- 3、查看函数向上的调用栈
- 4、查看执行代码流程
- 5、查看函数执行时间
- 6、查看函数执行时间 和函数向下执行流
- 7、查看函数执行时间 和 函数向下执行流 和函数向上执行流
- 8、使用option
- 9、使用set_ftrace_filter
- 10、使用kprobe
- 1、数据结构
- 2、数据类型 和 结构体偏移
- 3、添加和使用kprobe
- 4、输出日志
https://www.yuque.com/wangjianfeng-8fxdf/gaf2xs/gbk1zc#yRQlC
1、查看函数被执行
- 方式1、使用function_tracer
cat ./available_filter_functions | grep blk_update_request
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo blk_update_request > ./set_ftrace_filterecho function > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho !blk_update_request >> ./set_ftrace_filter
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
- 方式2、kprobe event
cat ./available_filter_functions | grep blk_update_request
# echo 'p blk_update_request' > ./kprobe_events
## cat ./kprobe_events
### p:kprobes/p_blk_update_request_0 blk_update_request
- 参考脚本
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo 'p blk_update_request' > ./kprobe_eventsecho 1 > ./events/kprobes/p_blk_update_request_0/enable # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo 0 > ./events/kprobes/p_blk_update_request_0/enable # turn offecho '-:p_blk_update_request_0' >> kprobe_events
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
2、查看模块的执行函数
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo '*:mod:my_modul' > ./set_ftrace_filterecho function > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho '!*:mod:ext4' >> ./set_ftrace_filter
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
3、查看函数向上的调用栈
- 方式1、使用function tracer
cat ./available_filter_functions | grep vfs_open
cat ./available_filter_functions | grep bio_add_page
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo bio_add_page > ./set_ftrace_filter
echo vfs_open >> ./set_ftrace_filter
echo 1 > ./options/func_stack_traceecho function > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho 0 > ./options/func_stack_trace
echo !bio_add_page >> ./set_ftrace_filter
echo !vfs_open >> ./set_ftrace_filter
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
- 方式2、使用kprobe event
cat ./available_filter_functions | grep vfs_open
# echo 'p vfs_open' > ./kprobe_events
## cat ./kprobe_events
### p:kprobes/p_vfs_open_0 vfs_open
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo nop > current_tracer
echo 0 > ./tracing_on && echo > ./trace
echo 'p vfs_open' > ./kprobe_events
echo 1 > ./options/stacktrace
# or
# echo 'stacktrace' > ./events/kprobes/p_vfs_open_0/triggerecho 1 > ./events/kprobes/p_vfs_open_0/enable # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo 0 > ./events/kprobes/p_vfs_open_0/enable # turn off# echo '!stacktrace' > ./events/kprobes/p_vfs_open_0/trigger
echo 0 > ./options/stacktrace
echo '-:p_vfs_open_0' >> kprobe_events
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
- 方式3、一招制胜
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo nop > current_tracer
echo 0 > ./tracing_on && echo > ./traceecho 'blk_update_request:stacktrace' > ./set_ftrace_filter
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo "!blk_update_request:stacktrace" > ./set_ftrace_filtercat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
4、查看执行代码流程
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-forkecho function > ./current_tracer
echo 'bio_add_page:traceon:1' > ./set_ftrace_filter
echo 'blk_update_request:traceoff:1' >> ./set_ftrace_filter
echo 'blk_update_request:stacktrace:1' >> ./set_ftrace_filter
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo nop > ./current_tracerecho '!bio_add_page:traceon:count' >> ./set_ftrace_filter
echo '!blk_update_request:traceoff:count' >> ./set_ftrace_filter
echo '!blk_update_request:stacktrace:count' >> ./set_ftrace_filter
echo 0 > ./options/function-fork
echo > ./set_ftrace_pidcat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
5、查看函数执行时间
cat ./available_filter_functions | grep blk_update_request
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo bio_add_page > ./set_ftrace_filter
echo vfs_open >> ./set_ftrace_filter
echo 1 > ./options/funcgraph-proc # show process name
echo function_graph > ./current_tracer
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-fork
echo 1 > ./options/pause-on-traceecho function_graph > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho 0 > ./options/pause-on-trace
echo 0 > ./options/function-fork
echo > ./set_ftrace_pid
echo 0 > ./options/funcgraph-proc
echo '!bio_add_page' >> ./set_ftrace_filter
echo '!vfs_open' >> ./set_ftrace_filtercat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
6、查看函数执行时间 和函数向下执行流
cat ./available_filter_functions | grep vfs_open
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo vfs_open > ./set_graph_function
echo 1 > ./options/funcgraph-proc # show process name
echo 1 > ./options/funcgraph-tail # add funcgraph tail
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-fork
echo 1 > ./options/pause-on-traceecho function_graph > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho 0 > ./options/pause-on-trace
echo 0 > ./options/function-fork
echo > ./set_ftrace_pid
echo 0 > ./options/funcgraph-tail
echo 0 > ./options/funcgraph-proc
echo '!vfs_open' >> ./set_graph_functioncat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
7、查看函数执行时间 和 函数向下执行流 和函数向上执行流
cat ./available_filter_functions | grep bio_add_page
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo bio_add_page >> ./set_graph_function
echo 1 > ./options/funcgraph-proc # show process name
echo 1 > ./options/funcgraph-tail # add funcgraph tail
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-fork
echo 1 > ./options/pause-on-traceecho 'bio_add_page:stacktrace' > ./set_ftrace_filter
echo function_graph > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn off
echo '!bio_add_page:stacktrace' > ./set_ftrace_filterecho 0 > ./options/pause-on-trace
echo 0 > ./options/function-fork
echo > ./set_ftrace_pid # filter pid
echo 0 > ./options/funcgraph-tail # add funcgraph tail
echo 0 > ./options/funcgraph-proc # show process name
echo '!bio_add_page' >> ./set_graph_functioncat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
8、使用option
9、使用set_ftrace_filter
10、使用kprobe
- 获取磁盘名为例:使用kprobe event对函数bio_add_page进行参数输出
1、数据结构
// dev_name = bio->bi_bdev->bd_disk->disk_name
....
2、数据类型 和 结构体偏移
# 前置条件:编译内核前选'CONFIG_DEBUG_INFO'的配置项,否则vmlinux会缺少debug符号信息
hinzer@vm:~/lab/linux-trace-lesson$ gdb vmlinux(gdb) whatis bio_add_page
type = int (struct bio *, struct page *, unsigned int, unsigned int)# 方式一: 适用高版本gdb
(gdb) ptype /o struct bio
(gdb) ptype /o struct block_device
(gdb) ptype /o struct gendisk# 方式二: 适用低版本gdb
(gdb) p &((struct bio*)0)->bi_bdev
(gdb) p &((struct block_device*)0)->bd_disk
(gdb) p &((struct gendisk*)0)->disk_name
3、添加和使用kprobe
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo nop > ./current_tracer# 类比C语言:dev_name = bio->bi_bdev->bd_disk->disk_name
echo 'p bio_add_page dev_name=+0xc(+0x360(+0x8($arg1))):string' > ./kprobe_events
echo 1 > ./events/kprobes/p_bio_add_page_0/enable
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo 0 > ./events/kprobes/p_bio_add_page_0/enable
echo '-:p_bio_add_page_0' >> ./kprobe_eventscat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
- 添加链接描述
4、输出日志
# tracer: nop
#
# entries-in-buffer/entries-written: 24/24 #P:4
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |touch-105 [001] .... 1996.556330: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"kworker/u8:1-59 [002] .... 1996.577168: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"kworker/u8:1-59 [002] .... 1996.577305: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"kworker/u8:1-59 [002] .... 1996.577361: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"jbd2/vda-8-74 [002] .... 1996.579222: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"