trace(使用 trace-cmd 追踪内核)

使用 trace-cmd 追踪内核

trace-cmd 是一个易于使用,且特性浩繁、可用来追踪内核函数的下令。

在 之前的文章里,我先容了怎样使用ftrace来追踪内核函数。经过写入和读出文件来使用ftrace会变得很单调,以是我对它做了一个封装来运转带有选项的下令,以启用和禁用追踪、设置过滤器、查察输入、扫除输入等等。

trace-cmd下令是一个可以协助你做到这一点的东西。在这篇文章中,我使用trace-cmd来实行我在ftrace文章中所做的相反职责。由于会常常参考那篇文章,发起在阅读这篇文章之前先阅读它。

安装 trace-cmd

本文中一切的下令都运转在 root 用户下。

由于 ftrace机制被内置于内核中,因此你可以使用底下的下令举行验证它对否启用:

# mount | grep tracefs none on /sys/kernel/tracing type tracefs (rw,relatime,seclabel)

不外,你必要手动实验安装 trace-cmd下令:

# dnf install trace-cmd -y

列出可用的追踪器

当使用 ftrace时,你必需查察文件的内容以了解有哪些追踪器可用。但使用trace-cmd,你可以经过以下办法取得这些信息:

# trace-cmd list -t hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop

启用函数追踪器

在我 之前的文章中,我使用了两个追踪器,在这里我也会这么做。用function启用你的第一个追踪器:

$ trace-cmd start -p function plugin 'function'

查察追踪输入

一旦追踪器被启用,你可以经过使用 show参数来查察输入。这只体现了前 20 行以坚持例子的简略(见我之前的文章对输入的表明):

# trace-cmd show | head -20 ## tracer: function # # entries-in-buffer/entries-written: 410142/3380032 #P:8 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | gdbus-2606 [004] ..s. 10520.538759: __msecs_to_jiffies

中止追踪并扫除缓冲区

追踪将会在背景持续运转,你可以持续用 show查察输入。

要中止追踪,请运转带有 stop参数的trace-cmd下令:

# trace-cmd stop

要扫除缓冲区,用 clear参数运转它:

# trace-cmd clear

启用函数调用图追踪器

运转第二个追踪器,经过 function_graph参数来启用它。

# trace-cmd start -p function_graph Plugin 'function_graph'

再次使用 show参数查察输入。正如预期的那样,输入与第一次追踪输入略有不同。这一次,它包含一个函数调用链:

# trace-cmd show | head -20 ## tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 4) 0.079 us | } /* rcu_all_qs */ 4) 0.327 us | } /* __cond_resched */ 4) 0.081 us | rcu_read_unlock_strict; 4) | __cond_resched { 4) 0.078 us | rcu_all_qs; 4) 0.243 us | } 4) 0.080 us | rcu_read_unlock_strict; 4) | __cond_resched { 4) 0.078 us | rcu_all_qs; 4) 0.241 us | } 4) 0.080 us | rcu_read_unlock_strict; 4) | __cond_resched { 4) 0.079 us | rcu_all_qs; 4) 0.235 us | } 4) 0.095 us | rcu_read_unlock_strict; 4) | __cond_resched {

使用 stopclear下令来中止追踪和扫除缓存区:

# trace-cmd stop # trace-cmd clear

调停追踪以增长深度

假如你想在函数调用中看到更多的深度,你可以对追踪器举行调停:

# trace-cmd start -p function_graph --max-graph-depth 5 plugin 'function_graph'

如今,当你将这个输入与你之前看到的举行比力时,你应该看到更多的嵌套函数调用:

# trace-cmd show | head -20 ## tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 6) | __fget_light { 6) 0.804 us | __fget_files; 6) 2.708 us | } 6) 3.650 us | } /* __fdget */ 6) 0.547 us | eventfd_poll; 6) 0.535 us | fput; 6) | __fdget { 6) | __fget_light { 6) 0.946 us | __fget_files; 6) 1.895 us | } 6) 2.849 us | } 6) | sock_poll { 6) 0.651 us | unix_poll; 6) 1.905 us | } 6) 0.475 us | fput; 6) | __fdget {

了解可被追踪的函数

假如你想只追踪某些函数而忽略其他的,你必要晓得确切的函数称呼。你可以用 list -f参数来取得它们。比如搜刮稀有的内核函数kmalloc,它被用来在内核中分派内存:

# trace-cmd list -f | grep kmalloc bpf_map_kmalloc_node mempool_kmalloc __traceiter_kmalloc __traceiter_kmalloc_node kmalloc_slab kmalloc_order kmalloc_order_trace kmalloc_large_node __kmalloc __kmalloc_track_caller __kmalloc_node __kmalloc_node_track_caller [...]

底下是我的测试体系中可被追踪的函数总数:

# trace-cmd list -f | wc -l 63165

追踪内核模块干系的函数

你也可以追踪与特定内核模块干系的函数。假定你想追踪 kvm内核模块干系的功效,你可以经过以下办法来完成。请确保该模块以前加载:

# lsmod | grep kvm_intel kvm_intel 335872 0 kvm 987136 1 kvm_intel

再次运转 trace-cmd,使用list参数,并从输入后果中,grep查找以]开头的行。这将过滤掉内核模块。然后grep内核模块kvm_intel,你应该看到一切与该内核模块有关的函数。

# trace-cmd list -f | grep ]$ | grep kvm_intel vmx_can_emulate_instruction [kvm_intel] vmx_update_emulated_instruction [kvm_intel] vmx_setup_uret_msr [kvm_intel] vmx_set_identity_map_addr [kvm_intel] handle_machine_check [kvm_intel] handle_triple_fault [kvm_intel] vmx_patch_hypercall [kvm_intel] [...] vmx_dump_dtsel [kvm_intel] vmx_dump_sel [kvm_intel]

追踪特定函数

如今你晓得了怎样找到感兴致的函数,请用一个例子把这些内容用于时间。就像前方的文章一样,试着追踪与文件体系干系的函数。我的测试体系上的文件体系是 ext4

这个历程略有不同;你在运转下令时,不使用 start参数,而是在record参数后方加上你想追踪的函数的“形式”。你还必要指定你想要的追踪器;在这种情况下,就是function_graph。该下令会持续纪录追踪,直到你用Ctrl+C中止它。以是几秒钟后,按Ctrl+C中止追踪:

# trace-cmd list -f | grep ^ext4_ # trace-cmd record -l ext4_* -p function_graph plugin 'function_graph' Hit Ctrl^C to stop recording ^C CPU0 data recorded at offset=0x856000 8192 bytes in size [...]

查察追踪纪录

要查察你之前的追踪纪录,运转带有 report参数的下令。从输入后果来看,很分明过滤器起作用了,你只看到ext4干系的函数追踪:

# trace-cmd report | head -20 [...] cpus=8 trace-cmd-12697 [000] 11303.928103: funcgraph_entry: | ext4_show_options { trace-cmd-12697 [000] 11303.928104: funcgraph_entry: 0.187 us | ext4_get_dummy_policy; trace-cmd-12697 [000] 11303.928105: funcgraph_exit: 1.583 us | } trace-cmd-12697 [000] 11303.928122: funcgraph_entry: | ext4_create { trace-cmd-12697 [000] 11303.928122: funcgraph_entry: | ext4_alloc_inode { trace-cmd-12697 [000] 11303.928123: funcgraph_entry: 0.101 us | ext4_es_init_tree; trace-cmd-12697 [000] 11303.928123: funcgraph_entry: 0.083 us | ext4_init_pending_tree; trace-cmd-12697 [000] 11303.928123: funcgraph_entry: 0.141 us | ext4_fc_init_inode; trace-cmd-12697 [000] 11303.928123: funcgraph_exit: 0.931 us | } trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.081 us | ext4_get_dummy_policy; trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.133 us | ext4_get_group_desc; trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.115 us | ext4_free_inodes_count; trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.114 us | ext4_get_group_desc;

追踪一个特定的 PID

假定你想追踪与一个历程(PID)有关的函数。掀开另一个终端,注意运转中的 shell 的PID:

# echo $$ 10885

再次运转 record下令,用-P选项转达PID。这一次,让终端运转(也就是说,先不要按Ctrl+C):

# trace-cmd record -P 10885 -p function_graph Plugin 'function_graph' Hit Ctrl^C to stop recording

在 shell 上运转一些下令

挪动到另一个终端,在那边你有一个以特定 PID 运转的 shell,并运转任何下令,比如,ls下令用来列出文件:

# ls Temp-9b61f280-fdc1-4512-9211-5c60f764d702 tracker-extract-3-files.1000 v8-compile-cache-1000 [...]

挪动到你启用追踪的终端,按 Ctrl+C中止追踪:

# trace-cmd record -P 10885 -p function_graph plugin 'function_graph' Hit Ctrl^C to stop recording ^C CPU1 data recorded at offset=0x856000 618496 bytes in size [...]

在追踪的输入中,你可以看到右方是 PID 和 Bash shell,右方是与之干系的函数调用。这关于变小你的追踪范围好坏常便利的:

# trace-cmd report | head -20 cpus=8

试一试

这些简略的例子体现了使用 trace-cmd下令而不是底层的ftrace机制,是怎样完成既容易使用又拥有丰厚的功效,很多内容本文并没有触及。要想了解更多信息并更好地使用它,请查阅它的手册,并实验使用其他有效的下令。

via: https://opensource.com/article/21/7/linux-kernel-trace-cmd

作者:Gaurav Kamathe选题:lujun9972译者:萌新阿岩校正:wxy

本文由 LCTT原创编译,Linux中国荣誉推出

内容底部广告位(手机)
标签:

管理员
草根站长管理员

专注网站优化+网络营销,只做有思想的高价值网站,只提供有担当的营销服务!

上一篇:空腹血糖7一8之间不管能行吗(员工每天拉屎耗时3-6小时,被公司解雇!法院:超出正常生理需求范围)
下一篇:返回列表

相关推荐