GNU/Linux >> Belajar Linux >  >> Linux

Analisis kernel Linux dengan ftrace

Kernel sistem operasi adalah salah satu perangkat lunak yang paling sulit dipahami di luar sana. Itu selalu berjalan di latar belakang sejak sistem Anda dihidupkan. Setiap pengguna mencapai pekerjaan komputasi mereka dengan bantuan kernel, namun mereka tidak pernah berinteraksi dengannya secara langsung. Interaksi dengan kernel terjadi dengan melakukan panggilan sistem atau panggilan tersebut dilakukan atas nama pengguna oleh berbagai perpustakaan atau aplikasi yang mereka gunakan sehari-hari.

Saya telah membahas cara melacak panggilan sistem di artikel sebelumnya menggunakan strace . Namun, dengan strace , visibilitas Anda terbatas. Ini memungkinkan Anda untuk melihat panggilan sistem yang dipanggil dengan parameter tertentu dan, setelah pekerjaan selesai, melihat nilai kembalian atau status yang menunjukkan apakah mereka lulus atau gagal. Namun Anda tidak tahu apa yang terjadi di dalam kernel selama ini. Selain hanya melayani panggilan sistem, ada banyak aktivitas lain yang terjadi di dalam kernel yang tidak Anda sadari.

Pengantar Ftrace

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

Artikel ini bertujuan untuk menjelaskan penelusuran fungsi kernel dengan menggunakan mekanisme yang disebut ftrace . Itu membuat penelusuran kernel mudah diakses oleh pengguna Linux mana pun, dan dengan bantuannya Anda dapat belajar banyak tentang internal kernel Linux.

Output default yang dihasilkan oleh ftrace seringkali masif, mengingat kernel selalu sibuk. Untuk menghemat ruang, saya meminimalkan output dan, dalam banyak kasus, memotong output seluruhnya.

Saya menggunakan Fedora untuk contoh-contoh ini, tetapi mereka harus bekerja pada salah satu distribusi Linux terbaru.

Mengaktifkan ftrace

Ftrace adalah bagian dari kernel Linux sekarang, dan Anda tidak perlu lagi menginstal apa pun untuk menggunakannya. Kemungkinan, jika Anda menggunakan OS Linux terbaru, ftrace sudah diaktifkan. Untuk memverifikasi bahwa ftrace fasilitas tersedia, jalankan perintah mount dan cari tracefs . Jika Anda melihat output seperti di bawah ini, ftrace diaktifkan, dan Anda dapat dengan mudah mengikuti contoh di artikel ini. Perintah ini harus dijalankan sebagai pengguna root (sudo tidak cukup.)

# pemasangan | grep tracefs
tidak ada di /sys/kernel/tracing jenis tracefs (rw,relatime,seclabel)

Untuk menggunakan ftrace , Anda harus terlebih dahulu menavigasi ke direktori khusus seperti yang ditentukan dalam perintah mount di atas, dari mana Anda akan menjalankan sisa perintah dalam artikel:

# cd /sys/kernel/tracing 

Alur kerja umum

Pertama-tama, Anda harus memahami alur kerja umum untuk menangkap jejak dan mendapatkan hasilnya. Jika Anda menggunakan ftrace langsung, tidak ada ftrace- khusus perintah khusus untuk dijalankan. Sebagai gantinya, pada dasarnya Anda menulis ke beberapa file dan membaca dari beberapa file menggunakan utilitas baris perintah Linux standar.

Langkah-langkah umum:

  1. Tulis ke beberapa file tertentu untuk mengaktifkan/menonaktifkan pelacakan.
  2. Tulis ke beberapa file tertentu untuk menyetel/menghapus filter guna menyempurnakan penelusuran.
  3. Baca keluaran jejak yang dihasilkan dari file berdasarkan 1 dan 2.
  4. Hapus keluaran atau buffer sebelumnya dari file.
  5. Persempit ke kasus penggunaan khusus Anda (fungsi kernel untuk melacak) dan ulangi langkah 1, 2, 3, 4.

Jenis pelacak yang tersedia

Ada beberapa jenis pelacak yang tersedia untuk Anda. Seperti yang disebutkan sebelumnya, Anda harus berada di direktori tertentu sebelum menjalankan salah satu dari perintah ini karena file yang diinginkan ada di sana. Saya menggunakan jalur relatif (sebagai lawan dari jalur absolut) dalam contoh saya.

Anda dapat melihat konten available_tracers file untuk melihat semua jenis pelacak yang tersedia. Anda dapat melihat beberapa yang tercantum di bawah ini. Jangan khawatir tentang semuanya dulu:

# pwd
/sys/kernel/tracing

# cat available_tracers
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop

Dari semua pelacak yang diberikan, saya fokus pada tiga yang spesifik:function dan function_graph untuk mengaktifkan pelacakan, dan nop untuk menonaktifkan pelacakan.

Identifikasi pelacak saat ini

Biasanya, secara default, pelacak diatur ke nop . Artinya, "Tidak ada operasi" di file khusus current_tracer , yang biasanya berarti penelusuran saat ini tidak aktif:

# pwd
/sys/kernel/tracing

# cat current_tracer
nop

Lihat keluaran Pelacakan

Sebelum Anda mengaktifkan pelacakan apa pun, lihat file tempat hasil pelacakan disimpan. Anda dapat melihat konten file bernama trace menggunakan perintah cat:

# cat trace

# tracer:nop
#
# entries-in-buffer/entries-written:0/0   #P:8
#
#                                _-----=> irqs-off
#                             / _---=         |      | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  |||| TIMESTAMP  FUNGSI
#              | | | |||| | |

Aktifkan pelacak fungsi

Anda dapat mengaktifkan pelacak pertama Anda yang disebut function dengan menulis function ke file current_tracer (konten sebelumnya adalah nop , menunjukkan bahwa pelacakan tidak aktif.) Anggap operasi ini sebagai cara untuk mengaktifkan pelacakan:

# pwd
/sys/kernel/tracing

# cat current_tracer
nop

# echo function> current_tracer

# cat current_tracer
fungsi

Lihat keluaran penelusuran yang diperbarui untuk pelacak fungsi

Sekarang setelah Anda mengaktifkan pelacakan, saatnya untuk melihat hasilnya. Jika Anda melihat konten trace file, Anda melihat banyak data yang ditulis terus menerus. Saya telah menyalurkan output dan saat ini saya hanya melihat 20 baris teratas agar semuanya dapat dikelola. Jika Anda mengikuti header di output di sebelah kiri, Anda dapat melihat tugas dan ID Proses mana yang berjalan di CPU mana. Di sebelah kanan output, Anda melihat fungsi kernel yang tepat berjalan, diikuti oleh fungsi induknya. Ada juga informasi cap waktu di tengah:

# sudo cat trace | head -20

# pelacak:fungsi
#
# entri-in-buffer/entries-written:409936/4276216   #P:8
#
#                                _-----=> irqs-off
#                             / _---=> perlu diubah        |       | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  |||| TIMESTAMP  FUNGSI
#              | | | |||| | |
          -0       [000] d...  2088.841739:tsc_verify_tsc_adjust <-arch_cpu_idle_enter
          -0       [000] _ ... 39:2088 menganggur>-0       [000] d...  2088.841740:rcu_nocb_flush_deferred_wakeup <-do_idle
          -0       [000] d...  2088.841740:tick_check     idle  >  000   idle ] d...  2088.841740:cpuidle_get_cpu_driver <-do_idle
          -0       [000] d...  2088.841740:cpuidle_not_available <-do_idle
       ] :cpuidle_select <-do_idle
          -0       [000] d...  2088.841741:menu_select <-do_idle
          -0       [000] d...  2088 /pra>

Ingat bahwa pelacakan aktif, yang berarti output pelacakan terus ditulis ke file pelacakan hingga Anda menonaktifkan pelacakan.

Matikan pelacakan

Mematikan pelacakan itu sederhana. Yang harus Anda lakukan adalah mengganti function pelacak dengan nop di current_tracer file dan pelacakan dimatikan:

# cat current_tracer
fungsi

# echo nop> current_tracer

# cat current_tracer
nop

Aktifkan pelacak function_graph

Sekarang coba pelacak kedua, yang disebut function_graph . Anda dapat mengaktifkannya menggunakan langkah yang sama seperti sebelumnya:tulis function_graph ke current_tracer berkas:

# echo function_graph> current_tracer

# cat current_tracer
function_graph

Menelusuri keluaran dari function_graph tracer

Perhatikan bahwa format keluaran trace berkas telah berubah. Sekarang, Anda dapat melihat ID CPU dan durasi eksekusi fungsi kernel. Selanjutnya, Anda melihat kurung kurawal yang menunjukkan awal suatu fungsi dan fungsi lain yang dipanggil dari dalamnya:

# jejak kucing | head -20

# pelacak:function_graph
#
# CPU  DURATION                  PANGGILAN FUNGSI
# | | | | | | |
 6)               | n_tty_write() {
 6)               | down_read() {
 6)               | __cond_resched() {
 6)   0,341 kami    | rcu_all_qs();
 6)   1,057 kami    | }
 6)   1,807 kami    | }
 6)   0,402 kami    | process_echoes();
 6)               | add_wait_queue() {
 6)   0.391 kami    | _raw_spin_lock_irqsave();
 6)   0.359 kami    | _raw_spin_unlock_irqrestore();
 6)   1.757 kami    | }
 6)   0.350 kami    | tty_hung_up_p();
 6)               | mutex_lock() {
 6)               | __cond_resched() {
 6)   0,404 kami    | rcu_all_qs();
 6)   1,067 kami    | }

Aktifkan setelan pelacakan untuk meningkatkan kedalaman penelusuran

Anda selalu dapat mengubah sedikit pelacak untuk melihat lebih dalam dari panggilan fungsi menggunakan langkah-langkah di bawah ini. Setelah itu, Anda dapat melihat konten trace file dan lihat bahwa outputnya sedikit lebih detail. Untuk keterbacaan, output dari contoh ini dihilangkan:

# cat max_graph_depth
0

# echo 1> max_graph_depth ## atau:
# echo 2> max_graph_depth

# sudo cat trace

Menemukan fungsi untuk dilacak

Langkah-langkah di atas sudah cukup untuk memulai penelusuran. Namun, jumlah output yang dihasilkan sangat besar, dan Anda sering tersesat saat mencoba mencari item yang menarik. Seringkali Anda menginginkan kemampuan untuk melacak fungsi tertentu saja dan mengabaikan yang lainnya. Tetapi bagaimana Anda tahu proses mana yang harus dilacak jika Anda tidak tahu nama persisnya? Ada file yang dapat membantu Anda dalam hal ini—available_filter_functions memberi Anda daftar fungsi yang tersedia untuk dilacak:

# wc -l available_filter_functions  
63165 available_filter_functions

Mencari fungsi kernel umum

Sekarang coba cari fungsi kernel sederhana yang Anda ketahui. Ruang pengguna memiliki malloc untuk mengalokasikan memori, sedangkan kernel memiliki kmalloc fungsi, yang menyediakan fungsionalitas serupa. Di bawah ini adalah semua kmalloc fungsi terkait:

# grep kmalloc available_filter_functions
debug_kmalloc
mempool_kmalloc
kmalloc_slab
kmalloc_order
kmalloc_order_trace
kmalloc_fix_flags
kmalloc_large_node
__kmalloc>__kmalloc_track_caller
__kmalloc_node
__kmalloc_node_track_caller
[...]

Cari modul kernel atau fungsi terkait driver

Dari keluaran available_filter_functions , Anda dapat melihat beberapa baris yang diakhiri dengan teks dalam tanda kurung, seperti [kvm_intel] dalam contoh di bawah ini. Fungsi-fungsi ini terkait dengan modul kernel kvm_intel , yang sedang dimuat. Anda dapat menjalankan lsmod perintah untuk memverifikasi:

# grep kvm available_filter_functions | tail
__pi_post_block [kvm_intel]
vmx_vcpu_pi_load [kvm_intel]
vmx_vcpu_pi_put [kvm_intel]
pi_pre_block [kvm_intel]
pi_post_block [kvm_intel] br />pi_has_pending_interrupt [kvm_intel]
pi_update_irte [kvm_intel]
vmx_dump_dtsel [kvm_intel]
vmx_dump_sel [kvm_intel]

# lsmod  | grep -i kvm
kvm_intel             335872  0
kvm                   987136  1 kvm_intel
irqbypass               16

Hanya melacak fungsi tertentu

Untuk mengaktifkan pelacakan fungsi atau pola tertentu, Anda dapat menggunakan set_ftrace_filter file untuk menentukan fungsi mana dari output di atas yang ingin Anda lacak.

File ini juga menerima * pattern, yang diperluas untuk menyertakan fungsi tambahan dengan pola yang diberikan. Sebagai contoh, saya menggunakan ext4 sistem file di mesin saya. Saya dapat menentukan ext4 fungsi kernel tertentu untuk dilacak menggunakan perintah berikut:

# pemasangan | grep home
/dev/mapper/fedora-home di /home ketik ext4 (rw,relatime,seclabel)

# pwd
/sys/kernel/tracing

# cat set_ftrace_filter

#### semua fungsi diaktifkan ####
$
$ echo ext4_*> set_ftrace_filter
$
$ cat set_ftrace_filter
ext4_has_free_clusters
ext4_validate_block_bitmap
ext4_get_group_number
ext4_get_group_no_and_offset
ext4_get_group_desc
[...]

Sekarang, ketika Anda melihat hasil penelusuran, Anda hanya dapat melihat fungsi ext4 terkait dengan fungsi kernel yang telah Anda atur filternya sebelumnya. Semua keluaran lainnya diabaikan:

# cat trace |head -20

## tracer:function
#
# entries-in-buffer/entries-written:3871/3871   #P:8
#
#                                _-----=> irqs-off
#                             / _-- 
perlu / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  |||| TIMESTAMP  FUNGSI
#              | | | |||| | |
           cupsd-1066    [004] ....  3308.989545:ext4_file_getattr <-vfs_fstat
           cupsd-1066    [004] ....  3308_ _9547:ext  _9547:] ....  3308.989552:ext4_file_getattr <-vfs_fstat
           cupsd-1066    [004] ....  3308.989553:ext4_getattr <-ext4_file_getattr
                  . d_dentry_open
           cupsd-1066    [004] ....  3308.990111:ext4_file_getattr <-vfs_fstat
           cupsd-1066    [004] ....< berkas <4_getattr  3308. ] ....  3308.990122:ext4_llseek <-ksys_lseek
           cupsd-1066    [004] ....  3308.990130:ext4_file_read_iter <-new_sync_read

Mengecualikan fungsi agar tidak dilacak

Anda tidak selalu tahu apa yang ingin Anda lacak, tetapi Anda pasti tahu apa yang tidak ingin Anda lacak. Untuk itu, ada file ini dengan tepat bernama set_ftrace_notrace —perhatikan "tidak" di sana. Anda dapat menulis pola yang Anda inginkan dalam file ini dan mengaktifkan penelusuran, di mana semuanya kecuali pola yang disebutkan akan dilacak. Ini sering membantu untuk menghapus fungsionalitas umum yang mengacaukan keluaran kita:

# cat set_ftrace_notrace
#### tidak ada fungsi yang dinonaktifkan ####

Pelacakan yang ditargetkan

Sejauh ini, Anda telah menelusuri semua yang telah terjadi di kernel. Tapi itu tidak akan membantu kami jika Anda ingin melacak peristiwa yang terkait dengan perintah tertentu. Untuk mencapai ini, Anda dapat mengaktifkan dan menonaktifkan pelacakan sesuai permintaan dan, dan di antaranya, jalankan perintah pilihan kami sehingga Anda tidak mendapatkan output tambahan dalam output pelacakan Anda. Anda dapat mengaktifkan pelacakan dengan menulis 1 ke tracing_on , dan 0 untuk mematikannya:

# cat tracing_on
0

# echo 1> tracing_on

# cat tracing_on
1

## # Jalankan beberapa perintah khusus yang ingin kita lacak di sini ###

# echo 0> tracing_on

# cat tracing_on
0

Melacak PID tertentu

Jika Anda ingin melacak aktivitas yang terkait dengan proses tertentu yang sudah berjalan, Anda dapat menulis PID tersebut ke file bernama set_ftrace_pid dan kemudian aktifkan pelacakan. Dengan begitu, penelusuran terbatas pada PID ini saja, yang sangat membantu dalam beberapa kasus:

# echo $PID > set_ftrace_pid 

Kesimpulan

Ftrace adalah cara yang bagus untuk mempelajari lebih lanjut tentang cara kerja internal kernel Linux. Dengan beberapa latihan, Anda dapat belajar menyempurnakan ftrace dan mempersempit pencarian Anda. Untuk memahami ftrace lebih detail dan penggunaan lanjutannya, lihat artikel luar biasa yang ditulis oleh penulis inti ftrace dirinya—Steven Rostedt.

  • Men-debug kernel Linux, bagian 1
  • Men-debug kernel Linux, bagian 2
  • Men-debug kernel Linux, bagian 3

Linux
  1. Menjadwalkan tugas dengan perintah cron Linux

  2. Pengujian integrasi berkelanjutan untuk kernel Linux

  3. Linux – Berpartisipasi Di Milis Kernel?

  1. Kernel Linux:5 inovasi teratas

  2. Bagaimana cara men-debug kernel Linux dengan GDB dan QEMU?

  3. Debugging Kernel Linux dengan QEMU

  1. Jadwalkan tugas dengan Linux pada perintah

  2. Lakukan matematika di shell Linux dengan GNU bc

  3. Siklus hidup pengujian kernel Linux