ftrace之function及function_graph使用

2023-03-08 14:47:13 浏览数 (1)

一 用途

(1)function 主要用于跟踪内核函数的调用栈(其被调用过程)

(2)function_graph 主要用于跟踪内核函数内部调用流程及耗时

这两个对内核性能分析的作用不大,主要用来梳理内核模块的逻辑

二 使用

(1)function 使用

代码语言:javascript复制
/sys/kernel/debug/tracing # echo nop > current_tracer           ----清空跟踪器
/sys/kernel/debug/tracing # echo drm_open > set_ftrace_filter   ----设置跟踪函数为drm_open
/sys/kernel/debug/tracing # echo function > current_tracer      ----设置当前跟踪器
/sys/kernel/debug/tracing # echo 1 > options/func_stack_trace   ----跟踪函数调用栈
/sys/kernel/debug/tracing # echo 1 > tracing_on                 ----开始跟踪
/sys/kernel/debug/tracing # /mnt/vkms_test ---运行vkms_test程序,其会调用到内核drm_open函数
/sys/kernel/debug/tracing # echo 0 > tracing_on                 ----关闭跟踪
/sys/kernel/debug/tracing # cat trace                           ----查看跟踪结果
# tracer: function
#
# entries-in-buffer/entries-written: 2/2   #P:4
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  ||||   TIMESTAMP  FUNCTION
#              | |         |   ||||      |         |
       vkms_test-90      [001] ....  5408.290697: drm_open <-drm_stub_open
       vkms_test-90      [001] ....  5408.291126: <stack trace>
 => drm_stub_open
 => chrdev_open
 => do_dentry_open
 => vfs_open
 => path_openat
 => do_filp_open
 => do_sys_openat2
 => do_sys_open
 => sys_open
 => ret_fast_syscall
 => 0xbebc3cdc
/sys/kernel/debug/tracing # 

shell脚本:

代码语言:javascript复制
/mnt # cat trace_fun.sh 
# !/bin/sh
 
 
if [ $# -lt 2 ]; then
    echo "usage:"
    echo "  sh trace_func.sh function exec_file"
    exit -1
fi
 
cd /sys/kernel/debug/tracing/
echo nop > current_tracer
echo $1 > set_ftrace_filter
echo function > current_tracer
echo 1 > options/func_stack_trace
echo 1 > tracing_on
$2
echo 0 > tracing_on
cat trace
 
cd -

(2)function_graph使用

代码语言:javascript复制
/sys/kernel/debug/tracing # echo nop > current_tracer
/sys/kernel/debug/tracing # echo function_graph > current_tracer
/sys/kernel/debug/tracing # echo drm_open > set_graph_function
/sys/kernel/debug/tracing # echo 1 > options/funcgraph-tail ----增加函数尾部注释
/sys/kernel/debug/tracing # echo > set_ftrace_filter        ----清空,否则无法显示调用栈
/sys/kernel/debug/tracing # echo 1 > tracing_on 
/sys/kernel/debug/tracing # /mnt/vkms_test 
/sys/kernel/debug/tracing # echo 0 > tracing_on
/sys/kernel/debug/tracing # cat trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 2)               |  drm_open() {
 2)               |    drm_minor_acquire() {
 2)   8.625 us    |      _raw_spin_lock_irqsave();
 2)   4.709 us    |      _raw_spin_unlock_irqrestore();
 2)               |      drm_dev_enter() {
 2)   5.750 us    |        __srcu_read_lock();
 2)   17.167 us   |      } /* drm_dev_enter */
 2)   5.791 us    |      __srcu_read_unlock();
 2)   75.458 us   |    } /* drm_minor_acquire */
 2)   6.833 us    |    __drm_dbg();
 2)               |    drm_file_alloc() {
 2)               |      kmem_cache_alloc_trace() {
 2)   5.583 us    |        should_failslab();
 2)               |        __slab_alloc.constprop.19() {
 2)               |          ___slab_alloc.constprop.20() {
 2)   3.583 us    |            _raw_spin_lock();
 2)               |            alloc_debug_processing() {
 2)               |              check_slab() {
 2)   4.750 us    |                slab_pad_check.part.8();
 2)   12.375 us   |              } /* check_slab */
 2)               |              check_object() {
 2)   4.250 us    |                check_bytes_and_report();
 2)   4.166 us    |                check_bytes_and_report();
 2)   3.709 us    |                check_bytes_and_report();
 2)   3.250 us    |                check_bytes_and_report();
 2)   3.417 us    |                check_bytes_and_report();
 2)   39.792 us   |              } /* check_object */
 2)               |              set_track() {
 2)               |                stack_trace_save() {
 2)               |                  save_stack_trace() {
 2)               |                    __save_stack_trace() {
 2)   3.042 us    |                      save_trace();
 2)   2.958 us    |                      save_trace();
 2)   2.959 us    |                      save_trace();
 2)   2.959 us    |                      save_trace();
 2)   2.958 us    |                      save_trace();
 2)   3.000 us    |                      save_trace();
 2)   3.166 us    |                      save_trace();
 2)   3.042 us    |                      save_trace();
 2)   3.000 us    |                      save_trace();
 2)   3.000 us    |                      save_trace();
 2)   3.042 us    |                      save_trace();
 2)   3.041 us    |                      save_trace();
 2)   3.041 us    |                      save_trace();
 2)   3.000 us    |                      save_trace();
 2)   3.125 us    |                      save_trace();
 2)   3.000 us    |                      save_trace();
 2)   3.042 us    |                      save_trace();
 2)   3.042 us    |                      save_trace();
 2)   3.042 us    |                      save_trace();
 2)   3.083 us    |                      save_trace();
 2) ! 125.875 us  |                    } /* __save_stack_trace */
 2) ! 132.041 us  |                  } /* save_stack_trace */
 2) ! 138.375 us  |                } /* stack_trace_save */
 2) ! 145.208 us  |              } /* set_track */
 2)   4.375 us    |              init_object();
 2) ! 218.625 us  |            } /* alloc_debug_processing */
 2)               |            deactivate_slab() {
 2)   4.042 us    |              _raw_spin_lock();
 2)   16.833 us   |            } /* deactivate_slab */
 2) ! 257.708 us  |          } /* ___slab_alloc.constprop.20 */
 2) ! 272.709 us  |        } /* __slab_alloc.constprop.19 */
 2) ! 319.792 us  |      } /* kmem_cache_alloc_trace */
 2)               |      capable() {
 2)               |        ns_capable_common() {
 2)   6.500 us    |          cap_capable();
 2)   20.375 us   |        } /* ns_capable_common */
 2)   40.959 us   |      } /* capable */
 2)   5.958 us    |      __mutex_init();
 2)   6.792 us    |      __init_waitqueue_head();
 2)   5.791 us    |      __mutex_init();
 2)   7.084 us    |      drm_gem_open();
 2)               |      drm_prime_init_file_private() {
 2)   6.958 us    |        __mutex_init();
 2)   32.208 us   |      } /* drm_prime_init_file_private */
 2) ! 492.709 us  |    } /* drm_file_alloc */
 2)               |    drm_master_open() {
 2)   7.667 us    |      mutex_lock();
 2)               |      drm_new_set_master() {
 2)               |        drm_master_create() {
 2)               |          kmem_cache_alloc_trace() {
 2)   5.709 us    |            should_failslab();
 2)               |            __slab_alloc.constprop.19() {
 2)               |              ___slab_alloc.constprop.20() {
 2)   3.792 us    |                _raw_spin_lock();
 2)               |                alloc_debug_processing() {
 2)               |                  check_slab() {
 2)   3.417 us    |                    slab_pad_check.part.8();
 2)   10.291 us   |                  } /* check_slab */
 2)               |                  check_object() {
 2)   3.834 us    |                    check_bytes_and_report();
 2)   3.208 us    |                    check_bytes_and_report();
 2)   3.958 us    |                    check_bytes_and_report();
 2)   3.375 us    |                    check_bytes_and_report();
 2)   3.375 us    |                    check_bytes_and_report();
 2)   53.583 us   |                  } /* check_object */
 2)               |                  set_track() {
 2)               |                    stack_trace_save() {
 2)               |                      save_stack_trace() {
 2)               |                        __save_stack_trace() {
 2)   3.416 us    |                          save_trace();
 2)   3.042 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   2.958 us    |                          save_trace();
 2)   2.959 us    |                          save_trace();
 2)   3.042 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.125 us    |                          save_trace();
 2)   3.042 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.292 us    |                          save_trace();
 2)   3.083 us    |                          save_trace();
 2)   3.042 us    |                          save_trace();
 2)   2.959 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.000 us    |                          save_trace();
 2)   3.083 us    |                          save_trace();
 2) ! 137.583 us  |                        } /* __save_stack_trace */
 2) ! 143.833 us  |                      } /* save_stack_trace */
 2) ! 149.875 us  |                    } /* stack_trace_save */
 2) ! 156.166 us  |                  } /* set_track */
 2)   3.833 us    |                  init_object();
 2) ! 240.416 us  |                } /* alloc_debug_processing */
 2)               |                deactivate_slab() {
 2)   3.458 us    |                  _raw_spin_lock();
 2)   12.000 us   |                } /* deactivate_slab */
 2) ! 273.333 us  |              } /* ___slab_alloc.constprop.20 */
 2) ! 285.708 us  |            } /* __slab_alloc.constprop.19 */
 2) ! 310.667 us  |          } /* kmem_cache_alloc_trace */
 2) ! 324.167 us  |        } /* drm_master_create */
 2)   10.917 us   |        drm_set_master();
 2) ! 382.250 us  |      } /* drm_new_set_master */
 2)   6.333 us    |      mutex_unlock();
 2) ! 429.625 us  |    } /* drm_master_open */
 2)   6.500 us    |    mutex_lock();
 2)   5.708 us    |    mutex_unlock();
 2) # 1116.667 us |  } /* drm_open */
/sys/kernel/debug/tracing # 

shell脚本:

代码语言:javascript复制
/mnt # cat trace_fun_graph.sh 
# !/bin/sh
 
 
if [ $# -lt 2 ]; then
    echo "usage:"
    echo "  sh trace_func_graph.sh function exec_file"
    exit -1
fi
 
cd /sys/kernel/debug/tracing/
echo nop > current_tracer
echo function_graph > current_tracer
echo $1 > set_graph_function
echo 1 > options/funcgraph-tail
echo > set_ftrace_filter
echo 1 > tracing_on
$2
echo 0 > tracing_on
cat trace
 
cd -

0 人点赞