GNU/Linux >> Znalost Linux >  >> Linux

Trasování jádra pomocí trace-cmd

V mém předchozím článku jsem vysvětlil, jak používat ftrace ke sledování funkcí jádra. Pomocí ftrace zápis a čtení ze souborů může být zdlouhavé, takže jsem kolem toho použil obal ke spouštění příkazů s možnostmi povolení a zakázání trasování, nastavení filtrů, zobrazení výstupu, vymazání výstupu a další.

Příkaz trace-cmd je nástroj, který vám s tím pomůže. V tomto článku používám trace-cmd k provádění stejných úkolů, jaké jsem dělal ve svém ftrace článek. Vzhledem k tomu, že se na tento článek často vracím, doporučuji, abyste si jej přečetli dříve, než přečtete tento.

Instalovat trace-cmd

Příkazy v tomto článku spouštím jako uživatel root.

ftrace mechanismus je zabudován do jádra a jeho aktivaci můžete ověřit pomocí:

žádné na /sys/kernel/tracing typu tracefs (rw,relatime,seclabel)

Musíte však nainstalovat trace-cmd nástroj ručně.

# dnf install trace-cmd -y 

Seznam dostupných sledovacích prostředků

Při použití ftrace , musíte zobrazit obsah souboru, abyste viděli, jaké sledovací prvky jsou k dispozici. Ale pomocí trace-cmd , tyto informace můžete získat pomocí:

# trace-cmd list -t
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt funkce probuzení nop

Povolte sledování funkcí

Ve svém dřívějším článku jsem použil dva sledovače a zde udělám totéž. Povolte svůj první tracer, function , s:

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

Zobrazit výstup trasování

Jakmile je tracer povolen, můžete zobrazit výstup pomocí show argumenty. Toto zobrazuje pouze prvních 20 řádků, aby byl příklad krátký (vysvětlení výstupu viz můj dřívější článek):

# trace-cmd zobrazit | head -20
## tracer:funkce
#
# záznamy ve vyrovnávací paměti/zapsané záznamy:410142/3380032   #P:8
#
#                                -----=> irqs-off
#                               / _----=> potřeba změnit
#                               | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     zpoždění
#           TASK-PID     CPU#  |||| FUNKCE TIMESTAMP
#               | | | |||| | |
           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

Zastavit trasování a vymazat vyrovnávací paměť

Trasování pokračuje na pozadí a můžete pokračovat v prohlížení výstupu pomocí show .

Chcete-li zastavit trasování, spusťte trace-cmd pomocí stop argument:

# trace-cmd stop 

Chcete-li vymazat vyrovnávací paměť, spusťte ji pomocí clear argument:

# trace-cmd clear 

Povolit sledování function_graph

Povolte druhý sledovač, function_graph , spuštěním:

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

Ještě jednou si prohlédněte výstup pomocí show argument. Podle očekávání se výstup mírně liší od výstupu prvního trasování. Tentokrát obsahuje function calls řetěz:

# trace-cmd zobrazit | head -20
## tracer:function_graph
#
# CPU  DOBA TRVÁNÍ                  VOLÁNÍ FUNKCE
# | | | | | | |
 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() {

Použijte stop a clear příkazy k zastavení trasování a vymazání vyrovnávací paměti:

# trace-cmd stop
# trace-cmd clear

Vylepšením trasování zvýšíte hloubku

Pokud chcete vidět větší hloubku ve volání funkcí, můžete vyladit tracer:

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

Když nyní porovnáte tento výstup s tím, co jste viděli dříve, měli byste vidět více vnořených volání funkcí:

# trace-cmd zobrazit | head -20
## tracer:function_graph
#
# CPU  DOBA TRVÁNÍ                  VOLÁNÍ FUNKCE
# | | | | | | |
 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() {

Naučte se dostupné funkce ke sledování

Pokud chcete sledovat pouze určité funkce a zbytek ignorovat, musíte znát přesné názvy funkcí. Můžete je získat pomocí list argument následovaný -f . Tento příklad hledá společnou funkci jádra kmalloc , který se používá k alokaci paměti v jádře:

# seznam trace-cmd -f | grep kmalloc
bpf_map_kmalloc_node
mempool_kmalloc
__traceiter_kmalloc
__traceiter_kmalloc_node
kmalloc_slab
kmalloc_order
kmalloc_order_malloc_trace
>__kmalloc_track_caller
__kmalloc_node
__kmalloc_node_track_caller
[...]

Zde je celkový počet funkcí dostupných v mém testovacím systému:

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

Můžete také sledovat funkce související s konkrétním modulem jádra. Představte si, že chcete trasovat kvm funkce související s modulem jádra. Ujistěte se, že je modul načten:

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

Spusťte trace-cmd znovu pomocí list argument a z výstupu grep pro řádky, které končí ] . Tím se odfiltrují moduly jádra. Poté grep modul jádra kvm_intel a měli byste vidět všechny funkce související s tímto modulem jádra:

# seznam trace-cmd -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_m_mapintel_addr] [handkvx_set_identity_mtriintel_addr] [handkvx_set_identity_mtriintel_addr] [handkv
vmx_patch_hypercall [kvm_intel]

[...]

vmx_dump_dtsel [kvm_intel]
vmx_dump_sel [kvm_intel]

Další zdroje pro Linux

  • Cheat pro příkazy Linuxu
  • Cheat sheet pro pokročilé příkazy systému Linux
  • Bezplatný online kurz:Technický přehled RHEL
  • Síťový cheat pro Linux
  • Cheat sheet SELinux
  • Cheat pro běžné příkazy pro Linux
  • Co jsou kontejnery systému Linux?
  • Naše nejnovější články o Linuxu

Sledování specifických funkcí

Nyní, když víte, jak najít funkce, které vás zajímají, použijte tyto znalosti na příkladu. Stejně jako v předchozím článku zkuste vysledovat funkce související se souborovým systémem. Souborový systém, který jsem měl na svém testovacím systému, byl ext4 .

Tento postup je mírně odlišný; místo start , spustíte příkaz s record argument následovaný "vzorem" funkcí, které chcete trasovat. Musíte také určit sledovač, který chcete; v tomto případě je to function_graph . Příkaz pokračuje v záznamu trasování, dokud jej nezastavíte pomocí Ctrl+C . Po několika sekundách tedy stiskněte Ctrl+C pro zastavení sledování:

# seznam trace-cmd -f | grep ^ext4_

# záznam trace-cmd -l ext4_* -p function_graph
  plugin 'function_graph'
K zastavení nahrávání stiskněte Ctrl^C
^C
Data CPU0 zaznamenaná s offsetem=0x856000
    Velikost 8192 bajtů
[...]

Zobrazit zaznamenanou trasu

Chcete-li zobrazit trasování, které jste zaznamenali dříve, spusťte příkaz s report argument. Z výstupu je jasné, že filtr fungoval a vidíte pouze trasování funkce související s ext4:

# zpráva trace-cmd | 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();

Sledování konkrétního PID

Řekněme, že chcete sledovat funkce související s konkrétním trvalým identifikátorem (PID). Otevřete další terminál a poznamenejte si PID běžícího shellu:

# echo $$
10885

Spusťte record znovu a předejte PID pomocí -P volba. Tentokrát nechte terminál běžet (tj. netiskněte Ctrl+C ještě):

# trace-cmd record -P 10885 -p function_graph
  plugin 'function_graph'
K zastavení nahrávání stiskněte Ctrl^C

Spusťte nějakou aktivitu na shellu

Přejděte zpět na druhý terminál, kde jste měli spuštěný shell se specifickým PID, a spusťte libovolný příkaz, např. ls pro výpis souborů:

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

Přejděte zpět do terminálu, kde jste povolili trasování, a stiskněte Ctrl+C pro zastavení sledování:

# záznam trace-cmd -P 10885 -p function_graph
  plugin 'function_graph'
Stisknutím Ctrl^C záznam zastavíte
^C
Data CPU1 zaznamenaná s offsetem=0x856000
    Velikost 618496 bajtů
[...]

Ve výstupu trasování můžete vidět PID a shell Bash vlevo a volání funkcí s nimi související vpravo. To může být docela užitečné pro zúžení trasování:

# zpráva trace-cmd  | head -20

cpus=8
          -0     [001] 11555.380581:funcgraph_entry:                  | switch_mm_irqs_off() {
          -0     [001] 11555.380583:funcgraph_entry:       1.703 us   | load_new_mm_cr3();
          -0     [001] 11555,380586:funcgraph_entry:       0,493 us   | switch_ldt();
          -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() {

Vyzkoušejte to

Tyto krátké příklady ukazují, jak používat trace-cmd místo základního ftrace mechanismus se snadno používá a je bohatý na funkce, včetně mnoha, které jsem zde nepopsal. Chcete-li se dozvědět více a zlepšit se v něm, podívejte se na jeho manuálovou stránku a vyzkoušejte jeho další užitečné příkazy.


Linux
  1. CentOS / RHEL:Vyloučení s Yum pro aktualizace jádra

  2. Kompilace GNU/Linux s optimalizací -O3

  3. Mohu Qemu ukončit se selháním při panice jádra?

  1. Blokování aktualizací jádra pomocí Dpkg?

  2. Chyba při načítání modulu Btusb s jádrem 4.10.0-20-generic?

  3. Linux Centos s časovým razítkem dmesg

  1. Jak napsat svůj vlastní modul linuxového jádra s jednoduchým příkladem

  2. Jak ladit linuxové jádro pomocí GDB a QEMU?

  3. Jak sestavit modul jádra Linuxu tak, aby byl kompatibilní se všemi verzemi jádra?