抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

1 初探ftrace遇到的问题

1.1 搞清楚ftrace是否标记出中断函数

根据官网的描述,funcgraph-irqs选项,用于表明是否追踪中断。因此关闭后就不会记录中断信息。

1
2
3
funcgraph-irqs

When disabled, functions that happen inside an interrupt will not be traced.

1.2 搞清楚为何两次ftrace开头不一样

由于ftrace是将数据保留在一个ring buffer中,当数据大于buffer容量时,旧的数据就会被丢弃。所有两次ftrace执行被丢弃的数据长度不同,导致看到两次的开头不同。

解决的方法很简单,通过buffer_size_kb将缓存开大即可。

1
echo 10000 > buffer_size_kb

2 使用ftrace追踪内核函数调用

ftrace是一个Linux内核特性,它可以让你去跟踪Linux内核的函数调用。

ftrace基本使用

通过操作/sys/kernel/debug/trace目录下的数据文件来使用ftrace。启动ftrace后ftrace会根据这些文件的内容执行对应的操作。

主要控制ftrace的文件如下:

  • trace,查看ftrace追踪的结果
  • tracing_on,控制ftrace的开关
    • echo 1 > tracing_on启动ftrace追踪
    • echo 0 > tracing_on停止ftrace追踪
  • current_tracer,设置当前使用的追踪器
    • 可以在available_tracers中查看都支持哪些追踪器
    • nop追踪器:将nop写入current_tracer不追踪任何事件,并刷新trace文件
    • function追踪器:追踪函数调用
    • function_graph追踪器:类似function追踪器,但是能比较直观的查看函数的调用关系
    • 更多追踪器可以看这里
  • set_ftrace_pid,指定要追踪的进程的pid
  • set_ftrace_filter,指定要追踪的函数名
    • set_ftrace_notrace,指定不要追踪的函数名
    • 支持*, !等通配符
  • 以此类推,详见

ftrace还提供很多选项来自定义追踪的信息,主要在trace_options文件中。当需要关闭某个选项如funcgraph-cpu时,在其开头加上no写入即可:echo nofuncgraph-cpu > trace_options

不同tracer下可以用的选项有所不同,但是大同小异,以function_graphtracer为例,有如下常用选项

  • function-fork
    • 当打开时,set_ftrace_pid中进程fork产生的子进程的pid也会自动加入set_ftrace_pid中,当set_ftrace_pid中的进程退出时其中的PIDs会自动移除
  • funcgraph-irqs
    • 关闭后,中断触发的函数将不会被追踪
  • funcgraph-duration
    • 显示函数执行的时间,以毫秒为单位
  • funcgraph-proc
    • 开启后将显示进程名,pid等信息
  • 更多选项内容看这里

上述trace_options中的内容与./options文件夹中的数据文件对应

使用ftrace追踪一个进程的内核函数调用过程

刷新一下trace

1
echo nop > current_tracer

设置tracer追踪器,并设置一些选项:

1
2
3
4
5
echo function_graph > current_tracer        # 使用function_graph追踪器
echo nofuncgraph-irqs > trace_options # 不跟踪中断
echo nofuncgraph-cpu > trace_options # 不显示cpu信息
echo nofuncgraph-duration > trace_options # 不显示执行时长
echo function-fork > trace_options # 自动跟踪子进程

设置要追踪进程的pid

1
echo 14137 > set_ftrace_pid  # 跟踪14137号进程

追踪一段时间后关闭

1
2
3
echo 1 > tracing_on
# 一段时间后...
echo 0 > tracing_on

查看trace文件的内容,就是追踪的结果了

1
cat trace

需要注意的是,trace数据文件的大小有限,当超出大小限制后trace信息前端会被抛弃(因为数据保存在一个ring buffer中)。可以通过修改buffer_size_kb文件的值来设置每个cpu能够记录的缓存大小。

1
cat buffer_size_kb

每个cpu的缓存是可以单独设定的,如果cpu的设置的缓存大小不一致,buffer_size_kb中就会显示X

1
2
echo 10000 > per_cpu/cpu0/buffer_size_kb
echo 100 > per_cpu/cpu1/buffer_size_kb

buffer_total_size_kb会记录总缓存大小

评论