Pada artikel saya sebelumnya, saya menjelaskan cara menggunakan ftrace
untuk melacak fungsi kernel. Menggunakan ftrace
dengan menulis dan membaca dari file bisa menjadi membosankan, jadi saya menggunakan pembungkus di sekitarnya untuk menjalankan perintah dengan opsi untuk mengaktifkan dan menonaktifkan pelacakan, menyetel filter, melihat keluaran, menghapus keluaran, dan banyak lagi.
Perintah trace-cmd adalah utilitas yang membantu Anda melakukan hal ini. Dalam artikel ini, saya menggunakan trace-cmd
untuk melakukan tugas yang sama seperti yang saya lakukan di ftrace
artikel. Karena saya sering merujuk kembali ke artikel itu, saya sarankan Anda membacanya sebelum membaca yang ini.
Instal trace-cmd
Saya menjalankan perintah dalam artikel ini sebagai pengguna root.
ftrace
mekanisme dibangun ke dalam kernel, dan Anda dapat memverifikasinya diaktifkan dengan:
# mount | grep tracefs
none on /sys/kernel/tracing type tracefs (rw,relatime,seclabel)
Namun, Anda perlu menginstal trace-cmd
utilitas secara manual.
# dnf install trace-cmd -y
Daftar pelacak yang tersedia
Saat menggunakan ftrace
, Anda harus melihat konten file untuk melihat pelacak apa yang tersedia. Tetapi dengan trace-cmd
, Anda bisa mendapatkan informasi ini dengan:
# trace-cmd list -t
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
Aktifkan pelacak fungsi
Dalam artikel saya sebelumnya, saya menggunakan dua pelacak, dan saya akan melakukan hal yang sama di sini. Aktifkan pelacak pertama Anda, function
, dengan:
$ trace-cmd start -p function
plugin 'function'
Melihat keluaran jejak
Setelah pelacak diaktifkan, Anda dapat melihat output dengan menggunakan show
argumen. Ini hanya menunjukkan 20 baris pertama untuk membuat contoh singkat (lihat artikel saya sebelumnya untuk penjelasan tentang output):
# 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 <-rebalance_domains
gdbus-2606 [004] ..s. 10520.538760: load_balance <-rebalance_domains
gdbus-2606 [004] ..s. 10520.538761: idle_cpu <-load_balance
gdbus-2606 [004] ..s. 10520.538762: group_balance_cpu <-load_balance
gdbus-2606 [004] ..s. 10520.538762: find_busiest_group <-load_balance
gdbus-2606 [004] ..s. 10520.538763: update_group_capacity <-update_sd_lb_stats.constprop.0
gdbus-2606 [004] ..s. 10520.538763: __msecs_to_jiffies <-update_group_capacity
gdbus-2606 [004] ..s. 10520.538765: idle_cpu <-update_sd_lb_stats.constprop.0
gdbus-2606 [004] ..s. 10520.538766: __msecs_to_jiffies <-rebalance_domains
Berhenti melacak dan menghapus buffer
Pelacakan terus berjalan di latar belakang, dan Anda dapat terus melihat output menggunakan show
.
Untuk menghentikan pelacakan, jalankan trace-cmd
dengan stop
argumen:
# trace-cmd stop
Untuk menghapus buffer, jalankan dengan clear
argumen:
# trace-cmd clear
Aktifkan pelacak function_graph
Aktifkan pelacak kedua, function_graph
, dengan menjalankan:
# trace-cmd start -p function_graph
plugin 'function_graph'
Sekali lagi, lihat output menggunakan show
argumen. Seperti yang diharapkan, outputnya sedikit berbeda dari output jejak pertama. Kali ini termasuk function calls
rantai:
# 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() {
Gunakan stop
dan clear
perintah untuk berhenti melacak dan menghapus buffer:
# trace-cmd stop
# trace-cmd clear
Tweak tracing untuk menambah kedalaman
Jika Anda ingin melihat lebih dalam panggilan fungsi, Anda dapat mengubah pelacak:
# trace-cmd start -p function_graph --max-graph-depth 5
plugin 'function_graph'
Sekarang ketika Anda membandingkan output ini dengan apa yang Anda lihat sebelumnya, Anda akan melihat lebih banyak panggilan fungsi bersarang:
# 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() {
Pelajari fungsi yang tersedia untuk dilacak
Jika Anda hanya ingin melacak fungsi tertentu dan mengabaikan yang lainnya, Anda perlu mengetahui nama fungsi yang tepat. Anda bisa mendapatkannya dengan list
argumen diikuti oleh -f
. Contoh ini mencari fungsi kernel umum kmalloc
, yang digunakan untuk mengalokasikan memori di kernel:
# 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
[...]
Berikut jumlah total fungsi yang tersedia di sistem pengujian saya:
# trace-cmd list -f | wc -l
63165
Melacak fungsi terkait modul kernel
Anda juga dapat melacak fungsi yang terkait dengan modul kernel tertentu. Bayangkan Anda ingin melacak kvm
fungsi terkait modul kernel. Pastikan modul dimuat:
# lsmod | grep kvm_intel
kvm_intel 335872 0
kvm 987136 1 kvm_intel
Jalankan trace-cmd
lagi dengan list
argumen, dan dari output, grep
untuk baris yang diakhiri dengan ]
. Ini akan menyaring modul kernel. Kemudian grep
modul kernel kvm_intel
, dan Anda akan melihat semua fungsi yang terkait dengan modul kernel tersebut:
# 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]
Lebih banyak sumber daya Linux
- Lembar contekan perintah Linux
- Lembar contekan perintah Linux tingkat lanjut
- Kursus online gratis:Ikhtisar Teknis RHEL
- Lembar contekan jaringan Linux
- Lembar contekan SELinux
- Lembar contekan perintah umum Linux
- Apa itu container Linux?
- Artikel Linux terbaru kami
Melacak fungsi tertentu
Sekarang setelah Anda tahu cara menemukan fungsi yang menarik, gunakan pengetahuan itu dengan sebuah contoh. Seperti pada artikel sebelumnya, coba lacak fungsi terkait sistem file. Sistem file yang saya miliki di sistem pengujian saya adalah ext4
.
Prosedur ini sedikit berbeda; alih-alih start
, Anda menjalankan perintah dengan record
argumen diikuti oleh "pola" fungsi yang ingin Anda lacak. Anda juga perlu menentukan pelacak yang Anda inginkan; dalam hal ini, itu function_graph
. Perintah terus merekam jejak hingga Anda menghentikannya dengan Ctrl+C . Jadi setelah beberapa detik, tekan Ctrl+C untuk berhenti melacak:
# 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
[...]
Melihat rekaman jejak
Untuk melihat jejak yang Anda rekam sebelumnya, jalankan perintah dengan report
argumen. Dari output, jelas bahwa filter berfungsi, dan Anda hanya melihat jejak fungsi terkait 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();
Lacak PID tertentu
Katakanlah Anda ingin melacak fungsi yang terkait dengan pengenal persisten (PID) tertentu. Buka terminal lain dan catat PID dari shell yang sedang berjalan:
# echo $$
10885
Jalankan record
perintah lagi dan berikan PID menggunakan -P
pilihan. Kali ini, biarkan terminal berjalan (yaitu, jangan tekan Ctrl+C belum):
# trace-cmd record -P 10885 -p function_graph
plugin 'function_graph'
Hit Ctrl^C to stop recording
Jalankan beberapa aktivitas di shell
Kembali ke terminal lain tempat Anda menjalankan shell dengan PID tertentu dan jalankan perintah apa pun, mis., ls
untuk membuat daftar file:
# ls
Temp-9b61f280-fdc1-4512-9211-5c60f764d702
tracker-extract-3-files.1000
v8-compile-cache-1000
[...]
Kembali ke terminal tempat Anda mengaktifkan pelacakan dan tekan Ctrl+C untuk berhenti melacak:
# 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
[...]
Dalam keluaran jejak, Anda dapat melihat PID dan shell Bash di sebelah kiri dan pemanggilan fungsi yang terkait dengannya di sebelah kanan. Ini bisa sangat berguna untuk mempersempit penelusuran Anda:
# trace-cmd report | head -20
cpus=8
<idle>-0 [001] 11555.380581: funcgraph_entry: | switch_mm_irqs_off() {
<idle>-0 [001] 11555.380583: funcgraph_entry: 1.703 us | load_new_mm_cr3();
<idle>-0 [001] 11555.380586: funcgraph_entry: 0.493 us | switch_ldt();
<idle>-0 [001] 11555.380587: funcgraph_exit: 7.235 us | }
bash-10885 [001] 11555.380589: funcgraph_entry: 1.046 us | finish_task_switch.isra.0();
bash-10885 [001] 11555.380591: funcgraph_entry: | __fdget() {
bash-10885 [001] 11555.380592: funcgraph_entry: 2.036 us | __fget_light();
bash-10885 [001] 11555.380594: funcgraph_exit: 3.256 us | }
bash-10885 [001] 11555.380595: funcgraph_entry: | tty_poll() {
bash-10885 [001] 11555.380597: funcgraph_entry: | tty_ldisc_ref_wait() {
bash-10885 [001] 11555.380598: funcgraph_entry: | ldsem_down_read() {
bash-10885 [001] 11555.380598: funcgraph_entry: | __cond_resched() {
Cobalah
Contoh singkat ini menunjukkan bagaimana menggunakan trace-cmd
alih-alih ftrace
yang mendasarinya mekanisme mudah digunakan dan kaya fitur, termasuk banyak yang tidak saya bahas di sini. Untuk mempelajari lebih lanjut dan menjadi lebih baik, lihat halaman manualnya dan coba perintah berguna lainnya.