Jádro operačního systému je jedním z nejnepolapitelnějších kusů softwaru. Vždy běží na pozadí od chvíle, kdy se váš systém zapne. Každý uživatel dosahuje své výpočetní práce s pomocí jádra, ale nikdy s ním přímo neinteraguje. Interakce s jádrem se uskutečňuje prostřednictvím systémových volání nebo tím, že tato volání provádějí jménem uživatele různé knihovny nebo aplikace, které denně používají.
Jak trasovat systémová volání jsem popsal v dřívějším článku pomocí strace
. Nicméně s strace
, vaše viditelnost je omezená. Umožňuje vám zobrazit vyvolaná systémová volání se specifickými parametry a po dokončení práce zobrazit návratovou hodnotu nebo stav indikující, zda prošla nebo selhala. Neměli jste ale ponětí, co se během této doby stalo uvnitř jádra. Kromě pouhého obsluhování systémových volání se uvnitř jádra odehrává spousta dalších aktivit, na které zapomínáte.
Úvod Ftrace
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
Tento článek si klade za cíl vnést trochu světla do trasování funkcí jádra pomocí mechanismu zvaného ftrace
. Díky tomu je sledování jádra snadno dostupné pro každého uživatele Linuxu a s jeho pomocí se můžete dozvědět hodně o vnitřních částech jádra Linuxu.
Výchozí výstup generovaný ftrace
je často masivní, vzhledem k tomu, že jádro je vždy zaneprázdněné. Abych ušetřil místo, omezil jsem výstup na minimum a v mnoha případech jsem výstup úplně zkrátil.
Pro tyto příklady používám Fedoru, ale měly by fungovat na jakékoli z nejnovějších distribucí Linuxu.
Povolení ftrace
Ftrace
je nyní součástí linuxového jádra a k jeho používání již není třeba nic instalovat. Pokud používáte nejnovější operační systém Linux, je pravděpodobné, že ftrace
je již povoleno. Chcete-li ověřit, že ftrace
zařízení je k dispozici, spusťte příkaz mount a vyhledejte tracefs
. Pokud vidíte výstup podobný tomu, který je uveden níže, ftrace
je povoleno a můžete snadno postupovat podle příkladů v tomto článku. Tyto příkazy musí být spuštěny jako uživatel root (sudo
je nedostatečné.)
Chcete-li použít ftrace
, nejprve musíte přejít do speciálního adresáře, jak je uvedeno v příkazu mount výše, odkud budete spouštět zbývající příkazy v článku:
# cd /sys/kernel/tracing
Obecný pracovní postup
Nejprve musíte pochopit obecný pracovní postup zachycení stopy a získání výstupu. Pokud používáte ftrace
přímo, neexistuje žádný speciální ftrace-
konkrétní příkazy ke spuštění. Místo toho v podstatě zapisujete do některých souborů a čtete z některých souborů pomocí standardních linuxových nástrojů příkazového řádku.
Obecné kroky:
- Chcete-li povolit/zakázat trasování, zapisujte do některých konkrétních souborů.
- Zapisováním do některých konkrétních souborů nastavte/zrušte nastavení filtrů za účelem doladění sledování.
- Čtení generovaného trasovacího výstupu ze souborů založených na 1 a 2.
- Vymažte dřívější výstup nebo vyrovnávací paměť ze souborů.
- Upřesněte na svůj konkrétní případ použití (funkce jádra ke sledování) a opakujte kroky 1, 2, 3, 4.
Typy dostupných sledovačů
K dispozici máte několik různých druhů sledovačů. Jak již bylo zmíněno dříve, před spuštěním kteréhokoli z těchto příkazů musíte být v určitém adresáři, protože tam jsou přítomny soubory, které vás zajímají. Ve svých příkladech používám relativní cesty (na rozdíl od absolutních cest).
Můžete si prohlédnout obsah available_tracers
zobrazíte všechny dostupné typy sledovačů. Některé z nich můžete vidět níže. Zatím se o všechny nestarejte:
# pwd
/sys/kernel/tracing
# cat available_tracers
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt funkce probuzení nop
Ze všech uvedených tracerů se zaměřuji na tři konkrétní:function
a function_graph
pro povolení trasování a nop
zakázat trasování.
Identifikujte aktuální sledovač
Obvykle je ve výchozím nastavení tracer nastaven na nop
. To znamená "Žádná operace" ve speciálním souboru current_tracer
, což obvykle znamená, že sledování je aktuálně vypnuté:
# pwd
/sys/kernel/tracing
# cat current_tracer
nop
Zobrazit výstup trasování
Než povolíte jakékoli trasování, podívejte se na soubor, do kterého se ukládá výstup trasování. Můžete zobrazit obsah souboru s názvem trace
pomocí příkazu cat:
# stopa pro kočky
# tracer:nop
#
# entries-in-buffer/entries-written:0/0 #P:8
#
# _-----=> irqs-off
# / _---- / _---- _----=br / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / zpoždění
# TASK-PID CPU# |||| FUNKCE TIMESTAMP
# | | | |||| | |
Povolit sledování funkcí
Můžete povolit svůj první sledovač s názvem function
zápisem function
do souboru current_tracer
(jeho dřívější obsah byl nop
, což znamená, že trasování bylo vypnuto.) Představte si tuto operaci jako způsob povolení trasování:
# pwd
/sys/kernel/tracing
# cat current_tracer
nop
# funkce echo> current_tracer
# cat current_tracer
funkce
Zobrazit aktualizovaný výstup trasování pro sledování funkcí
Nyní, když jste povolili trasování, je čas zobrazit výstup. Pokud zobrazíte obsah trace
soubor, vidíte, že se do něj nepřetržitě zapisuje spousta dat. Odeslal jsem výstup a v současné době si prohlížím pouze 20 nejlepších řádků, aby se věci daly zvládnout. Pokud budete postupovat podle záhlaví ve výstupu vlevo, můžete vidět, která úloha a ID procesu běží na kterém CPU. Směrem k pravé straně výstupu vidíte přesně spuštěnou funkci jádra, následovanou její rodičovskou funkcí. V centru je také informace o časovém razítku:
# sudo stopa kočky | head -20
# tracer:funkce
#
# entries-in-buffer/entries-written:409936/4276216 #P:8
#
# _-----=> irqs-off
# _----=> br / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / zpoždění
# TASK-PID CPU# |||| FUNKCE TIMESTAMP
# | | | |||| | |
-0 [000] d... 2088.841739:tsc_verify_tsc_adjust <-arch_cpu_idle_enter
n 0 . -0 0 . 4 d... 3> 0 . 4 d... Idle> -0 [000] D ... 2088.841740:RCU_NOCB_FLUSH_DEFERRED_WAKEUP <-DO_IDLE
-0 [000] d ... 2088.841740:tick_check_broadcast_expired <-do_idle
-0 [000 ] d... 2088.841740:cpuidle_get_cpu_driver <-do_idle
-0 [000] d... 0 2088.841740:cpuidle_not_idleable <-do> 0 :cpuidle_select <-do_idle
-0 [000] d... 2088.841741:menu_select <-do_idle
-0 -0 2 d... /před> Pamatujte, že trasování je zapnuté, což znamená, že výstup trasování se nadále zapisuje do souboru trasování, dokud trasování nevypnete.
Vypnout trasování
Vypnutí trasování je jednoduché. Jediné, co musíte udělat, je nahradit
function
tracer snop
vcurrent_tracer
soubor a trasování se vypnou:# cat current_tracer
funkce
# echo nop> current_tracer
# cat current_tracer
nopPovolit sledování funkce function_graph
Nyní vyzkoušejte druhý sledovač, nazvaný
function_graph
. Můžete to povolit pomocí stejných kroků jako dříve:napištefunction_graph
docurrent_tracer
soubor:# echo function_graph> current_tracer
# cat current_tracer
function_graphTrasování výstupu traceru function_graph
Všimněte si, že výstupní formát
trace
soubor se změnil. Nyní můžete vidět ID CPU a dobu provádění funkce jádra. Dále uvidíte složené závorky označující začátek funkce a jaké další funkce byly z ní volány:# stopa kočky | head -20
# tracer:function_graph
#
# CPU DOBA TRVÁNÍ VOLÁNÍ FUNKCE
# | | | | | | |
6) | n_tty_write() {
6) | down_read() {
6) | __cond_resched() {
6) 0,341 us | rcu_all_qs();
6) 1,057 us |
6) 1 807 us |
6) 0,402 us | process_echoes();
6) | add_wait_queue() {
6) 0,391 us | _raw_spin_lock_irqsave();
6) 0,359 us | _raw_spin_unlock_irqrestore();
6) 1,757 us |
6) 0,350 us | tty_hung_up_p();
6) | mutex_lock() {
6) | __cond_resched() {
6) 0,404 us | rcu_all_qs();
6) 1,067 us | }Povolením nastavení trasování zvýšíte hloubku trasování
Pomocí níže uvedených kroků můžete sledovač vždy mírně vyladit, abyste viděli větší hloubku volání funkcí. Poté si můžete prohlédnout obsah
trace
soubor a uvidíte, že výstup je o něco podrobnější. Kvůli čitelnosti je výstup tohoto příkladu vynechán:# cat max_graph_depth
0
# echo 1> max_graph_depth ## nebo:
# echo 2> max_graph_depth
# sudo cat traceHledání funkcí ke sledování
Výše uvedené kroky jsou dostatečné, abyste mohli začít s trasováním. Množství generovaného výstupu je však obrovské a často se můžete ztratit, když se snažíte najít zajímavé položky. Často chcete mít možnost sledovat pouze konkrétní funkce a zbytek ignorovat. Jak ale víte, které procesy sledovat, když neznáte jejich přesná jména? Existuje soubor, který vám s tím může pomoci –
available_filter_functions
vám poskytuje seznam dostupných funkcí pro trasování:# wc -l available_filter_functions
63165 available_filter_functionsVyhledejte obecné funkce jádra
Nyní zkuste vyhledat jednoduchou funkci jádra, které znáte. Uživatelský prostor má
malloc
pro alokaci paměti, zatímco jádro má svůjkmalloc
funkce, která poskytuje podobnou funkcionalitu. Níže jsou uvedeny všechnykmalloc
související funkce:# grep kmalloc available_filter_functions
debug_kmalloc
mempool_kmalloc
kmalloc_slab
kmalloc_order
kmalloc_order_trace
kmalloc_fix_flags
kmalloc_large_nodemal
>__kmalloc_track_caller
__kmalloc_node
__kmalloc_node_track_caller
[...]Vyhledejte funkce související s modulem jádra nebo ovladačem
Z výstupu
available_filter_functions
, můžete vidět některé řádky končící textem v hranatých závorkách, například[kvm_intel]
v níže uvedeném příkladu. Tyto funkce souvisí s modulem jádrakvm_intel
, který je aktuálně načten. Můžete spustitlsmod
příkaz k ověření:# grep kvm available_filter_functions | ocas
__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]pi_post_block] 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 3 před 16Sledování pouze specifických funkcí
Chcete-li povolit sledování konkrétních funkcí nebo vzorů, můžete použít
/dev/mapper/fedora-home na /home typ ext4 (rw,relatime,seclabel)set_ftrace_filter
soubor k určení, které funkce z výše uvedeného výstupu chcete sledovat.
Tento soubor také přijímá*
vzor, který se rozšíří o další funkce s daným vzorem. Jako příklad používámext4
souborový systém na mém počítači. Mohu zadatext4
konkrétní funkce jádra k trasování pomocí následujících příkazů:
# pwd
/sys/kernel/tracing
# cat set_ftrace_filter
#### všechny funkce povoleny ####
$
$ 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
[...]Nyní, když vidíte výstup trasování, můžete vidět pouze funkce
ext4
související s funkcemi jádra, pro které jste dříve nastavili filtr. Veškerý ostatní výstup bude ignorován:# stopování kočky |head -20
## tracer:funkce
#
# entries-in-buffer/entries-written:3871/3871 #P:8 >#
# _-----=> irqs-off
# / _----=/ _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / zpoždění
# TASK-PID CPU# |||| FUNKCE TIMESTAMP
# | | | |||| | |
Cupsd-1066 [004] .... 3308.989545:EXT4_FILE_GETATTR <-VFS_FSTAT
cupsd-1066 [004] .... 3308.989547:EXT4_GETATTRcupsd-1066 [004 ]. DO_DENTRY_OPEN
Cupsd-1066 [004] .... 3308.990111:ext4_file_getattr <-vfs_fstattr
cupsd-1066 [004] .... 3308.990111:EXT4_GETATTRcupsd-1066 [004 ] .... 3308.990122:ext4_llseek <-ksys_lseek
cupsd-1066 [004] .... 3308.990130:ext4_file_read_iter_read-new_>Vyloučit funkce ze sledování
Ne vždy víte, co chcete sledovat, ale určitě víte, co nechcete. K tomu existuje tento soubor s příhodným názvem
set_ftrace_notrace
– všimněte si tam „ne“. Do tohoto souboru můžete zapsat požadovaný vzor a povolit trasování, na kterém se bude sledovat vše kromě uvedeného vzoru. To je často užitečné k odstranění běžných funkcí, které ruší náš výstup:# cat set_ftrace_notrace
#### žádné funkce zakázány ####Cílené sledování
Doposud jste sledovali vše, co se v jádře stalo. Ale to nám nepomůže, pokud chcete sledovat události související s konkrétním příkazem. Chcete-li toho dosáhnout, můžete zapnout a vypnout trasování na požádání a mezi nimi spustit náš vybraný příkaz, abyste ve svém trasovacím výstupu nezískali další výstup. Trasování můžete povolit zápisem
1
natracing_on
a0
pro vypnutí:# sledování_koček
0
# echo 1> sledování_zapnutí
# sledování_koček
1
## # Spusťte nějaký konkrétní příkaz, který zde chceme trasovat ###
# echo 0> tracing_on
# cat tracing_on
0Sledování specifického PID
Pokud chcete sledovat aktivitu související s konkrétním procesem, který již běží, můžete toto PID zapsat do souboru s názvem
set_ftrace_pid
a poté povolte trasování. Tímto způsobem je trasování omezeno pouze na toto PID, což je v některých případech velmi užitečné:# echo $PID > set_ftrace_pid
Závěr
Ftrace
je skvělý způsob, jak se dozvědět více o vnitřním fungování linuxového jádra. S trochou praxe se můžete naučit doladitftrace
a zúžit vyhledávání. Pro pochopeníftrace
podrobněji a jeho pokročilé použití najdete v těchto vynikajících článcích napsaných hlavním autoremftrace
sám — Steven Rostedt.
- Ladění linuxového jádra, část 1
- Ladění linuxového jádra, část 2
- Ladění linuxového jádra, část 3
Linux