Der Kernel eines Betriebssystems ist eine der schwer fassbaren Softwareteile, die es gibt. Es läuft immer im Hintergrund, sobald Ihr System eingeschaltet wird. Jeder Nutzer erledigt seine Rechenarbeit mit Hilfe des Kernels, interagiert aber nie direkt mit ihm. Die Interaktion mit dem Kernel erfolgt, indem Systemaufrufe durchgeführt werden oder diese Aufrufe im Namen des Benutzers von verschiedenen Bibliotheken oder Anwendungen ausgeführt werden, die er täglich verwendet.
Ich habe in einem früheren Artikel behandelt, wie man Systemaufrufe mit strace
verfolgt . Allerdings mit strace
, Ihre Sichtbarkeit ist eingeschränkt. Es ermöglicht Ihnen, die mit bestimmten Parametern aufgerufenen Systemaufrufe anzuzeigen und nach getaner Arbeit den Rückgabewert oder Status anzuzeigen, der angibt, ob sie bestanden oder fehlgeschlagen sind. Aber Sie hatten keine Ahnung, was während dieser Zeit im Kernel passiert ist. Abgesehen davon, dass nur Systemaufrufe bedient werden, gibt es eine Menge anderer Aktivitäten innerhalb des Kernels, die Sie nicht bemerken.
Ftrace-Einführung
Weitere Linux-Ressourcen
- Spickzettel für Linux-Befehle
- Spickzettel für fortgeschrittene Linux-Befehle
- Kostenloser Online-Kurs:RHEL Technical Overview
- Spickzettel für Linux-Netzwerke
- SELinux-Spickzettel
- Spickzettel für allgemeine Linux-Befehle
- Was sind Linux-Container?
- Unsere neuesten Linux-Artikel
Dieser Artikel zielt darauf ab, etwas Licht in die Verfolgung der Kernelfunktionen zu bringen, indem ein Mechanismus namens ftrace
verwendet wird . Es macht Kernel-Tracing für jeden Linux-Benutzer leicht zugänglich, und mit seiner Hilfe können Sie viel über die Interna des Linux-Kernels lernen.
Die von ftrace
generierte Standardausgabe ist oft massiv, da der Kernel immer beschäftigt ist. Um Platz zu sparen, habe ich die Ausgabe auf ein Minimum beschränkt und in vielen Fällen die Ausgabe vollständig abgeschnitten.
Ich verwende Fedora für diese Beispiele, aber sie sollten auf jeder der neuesten Linux-Distributionen funktionieren.
FTrace aktivieren
Ftrace
ist jetzt Teil des Linux-Kernels und Sie müssen nichts mehr installieren, um es zu verwenden. Wenn Sie ein neueres Linux-Betriebssystem verwenden, ist es wahrscheinlich, dass ftrace
ist bereits aktiviert. Um zu überprüfen, ob der ftrace
Funktion verfügbar ist, führen Sie den Mount-Befehl aus und suchen Sie nach tracefs
. Wenn Sie eine ähnliche Ausgabe wie unten sehen, ftrace
aktiviert ist, und Sie können den Beispielen in diesem Artikel leicht folgen. Diese Befehle müssen als Root-Benutzer ausgeführt werden (sudo
ist nicht ausreichend.)
# montieren | grep tracefsein
keine auf /sys/kernel/tracing geben Sie tracefs (rw,relatime,seclabel)
Um ftrace
zu verwenden , müssen Sie zuerst zu dem speziellen Verzeichnis navigieren, das im obigen mount-Befehl angegeben ist, von wo aus Sie die restlichen Befehle im Artikel ausführen:
# cd /sys/kernel/tracing
Allgemeiner Arbeitsablauf
Zunächst müssen Sie den allgemeinen Arbeitsablauf zum Erfassen einer Ablaufverfolgung und zum Abrufen der Ausgabe verstehen. Wenn Sie ftrace
verwenden direkt, es gibt keinen speziellen ftrace-
bestimmte auszuführende Befehle. Stattdessen schreiben Sie im Grunde genommen in einige Dateien und lesen aus einigen Dateien mit Standard-Befehlszeilen-Linux-Dienstprogrammen.
Die allgemeinen Schritte:
- Schreiben Sie in einige spezifische Dateien, um die Ablaufverfolgung zu aktivieren/deaktivieren.
- Schreiben Sie in bestimmte Dateien, um Filter zur Feinabstimmung der Ablaufverfolgung festzulegen/zu deaktivieren.
- Lesen Sie generierte Ablaufverfolgungsausgaben aus Dateien basierend auf 1 und 2.
- Lösche frühere Ausgaben oder Puffer aus Dateien.
- Beschränken Sie sich auf Ihren spezifischen Anwendungsfall (zu verfolgende Kernel-Funktionen) und wiederholen Sie die Schritte 1, 2, 3, 4.
Arten verfügbarer Tracer
Es stehen Ihnen verschiedene Arten von Tracern zur Verfügung. Wie bereits erwähnt, müssen Sie sich in einem bestimmten Verzeichnis befinden, bevor Sie einen dieser Befehle ausführen, da die gewünschten Dateien dort vorhanden sind. Ich verwende in meinen Beispielen relative Pfade (im Gegensatz zu absoluten Pfaden).
Sie können den Inhalt der available_tracers
anzeigen Datei, um alle verfügbaren Tracer-Typen anzuzeigen. Sie können einige unten aufgelistet sehen. Machen Sie sich noch keine Gedanken über alle:
# pwd
/sys/kernel/tracing
# cat available_tracers
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt Wakeup-Funktion nop
Von allen angegebenen Tracern konzentriere ich mich auf drei spezifische:function
und function_graph
um die Ablaufverfolgung zu aktivieren, und nop
zum Deaktivieren der Ablaufverfolgung.
Aktuellen Tracer identifizieren
Normalerweise ist der Tracer standardmäßig auf nop
eingestellt . Das heißt, "No operation" in der speziellen Datei current_tracer
, was normalerweise bedeutet, dass die Ablaufverfolgung derzeit deaktiviert ist:
# pwd
/sys/kernel/tracing
# cat current_tracer
nop
Nachverfolgungsausgabe anzeigen
Bevor Sie das Tracing aktivieren, sehen Sie sich die Datei an, in der die Tracing-Ausgabe gespeichert wird. Sie können den Inhalt der Datei mit dem Namen trace
anzeigen mit dem cat-Befehl:
# Cat Trace
# Tracer:nop
#
# Einträge-im-Puffer/Einträge-geschrieben:0/0 #P:8
#
# _-----=> irqs-off
# / _----=> neu eingestellt
# | | | / _---=> hardirq/softirq
# || / _--=> Preempt-Tiefe
# ||| / delay
# TASK-PID CPU# |||| ZEITSTEMPELFUNKTION
# | | | |||| | |
Funktions-Tracer aktivieren
Sie können Ihren ersten Tracer namens function
aktivieren indem Sie function
schreiben in die Datei current_tracer
(der frühere Inhalt war nop
, was anzeigt, dass die Ablaufverfolgung deaktiviert war.) Stellen Sie sich diese Operation als Möglichkeit vor, die Ablaufverfolgung zu aktivieren:
# pwd
/sys/kernel/tracing
# cat current_tracer
nop
# echo function> current_tracer
# cat current_tracer
Funktion
Aktualisierte Tracing-Ausgabe für Funktions-Tracer anzeigen
Nachdem Sie die Ablaufverfolgung aktiviert haben, ist es an der Zeit, die Ausgabe anzuzeigen. Wenn Sie den Inhalt des trace
anzeigen Datei, sehen Sie, dass kontinuierlich viele Daten darauf geschrieben werden. Ich habe die Ausgabe weitergeleitet und sehe mir derzeit nur die obersten 20 Zeilen an, um die Dinge überschaubar zu halten. Wenn Sie den Überschriften in der Ausgabe links folgen, können Sie sehen, welche Task und Prozess-ID auf welcher CPU ausgeführt werden. Auf der rechten Seite der Ausgabe sehen Sie die genaue ausgeführte Kernelfunktion, gefolgt von ihrer übergeordneten Funktion. Es gibt auch Zeitstempelinformationen in der Mitte:
# sudo cat trace | Kopf -20
# Tracer:Funktion
#
# Einträge-im-Puffer/Einträge-geschrieben:409936/4276216 #P:8
#
# _----=> irqs-off
# / _----=> Bedarfsänderung
# / _---=> hardirq/softirq
# || / _--=> Preempt-Tiefe
# ||| / delay
# TASK-PID CPU# |||| ZEITSTEMPELFUNKTION
# | | | |||| | |
-0 [000] d... 2088.841739:tsc_verify_tsc_adjust <-arch_cpu_idle_enter
-0 [000] d... -0 Leerlauf>-0 [000] d... 2088.841740:rcu_nocb_flush_deferred_wakeup <-do_idle
-0 [000] d... 2088.841740:tick_check_broadcast_expired <-do_idle
] d... 2088.841740:cpuidle_get_cpu_driver <-do_idle
-0 [000] d... 2088.841740:cpuidle_not_available <-do_idle
-0 [0 1] :cpuidle_select <-do_idle
-0 [000] d... 2088.841741:menu_select <-do_idle
-0 [000] d... 2088.841741:cpuidle_goverq /pre> Denken Sie daran, dass die Ablaufverfolgung aktiviert ist, was bedeutet, dass die Ausgabe der Ablaufverfolgung weiterhin in die Ablaufverfolgungsdatei geschrieben wird, bis Sie die Ablaufverfolgung deaktivieren.
Nachverfolgung deaktivieren
Das Deaktivieren der Ablaufverfolgung ist einfach. Alles, was Sie tun müssen, ist
function
zu ersetzen Tracer mitnop
imcurrent_tracer
Datei und Ablaufverfolgung wird deaktiviert:# cat current_tracer
function
# echo nop> current_tracer
# cat current_tracer
nopFunction_graph-Tracer aktivieren
Probieren Sie nun den zweiten Tracer namens
function_graph
aus . Sie können dies mit den gleichen Schritten wie zuvor aktivieren:Schreiben Siefunction_graph
zumcurrent_tracer
Datei:# echo function_graph> current_tracer
# cat current_tracer
function_graphTracing-Ausgabe des function_graph-Tracers
Beachten Sie, dass das Ausgabeformat von
trace
Datei hat sich geändert. Jetzt können Sie die CPU-ID und die Dauer der Ausführung der Kernelfunktion sehen. Als nächstes sehen Sie geschweifte Klammern, die den Anfang einer Funktion anzeigen und welche anderen Funktionen von dort aus aufgerufen wurden:# Katzenspur | head -20
# tracer:function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
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 | }Nachverfolgungseinstellungen aktivieren, um die Nachverfolgungstiefe zu erhöhen
Sie können den Tracer jederzeit leicht anpassen, um mehr Tiefe der Funktionsaufrufe zu sehen, indem Sie die folgenden Schritte verwenden. Danach können Sie den Inhalt des
trace
anzeigen Datei und sehen Sie, dass die Ausgabe etwas detaillierter ist. Aus Gründen der Lesbarkeit wird die Ausgabe dieses Beispiels weggelassen:# cat max_graph_Tiefe
0
# echo 1> max_graph_Tiefe ## oder:
# echo 2> max_graph_Tiefe
# sudo cat traceZu verfolgende Funktionen finden
Die obigen Schritte reichen aus, um mit der Ablaufverfolgung zu beginnen. Die erzeugte Ausgabemenge ist jedoch enorm, und Sie können sich oft verirren, wenn Sie versuchen, interessante Dinge herauszufinden. Oft möchten Sie nur bestimmte Funktionen verfolgen und den Rest ignorieren. Aber woher wissen Sie, welche Prozesse verfolgt werden müssen, wenn Sie ihre genauen Namen nicht kennen? Es gibt eine Datei, die Ihnen dabei helfen kann –
available_filter_functions
stellt Ihnen eine Liste der verfügbaren Funktionen für das Tracing zur Verfügung:# wc -l verfügbare_filter_funktionen
63165 verfügbare_filter_funktionenNach allgemeinen Kernelfunktionen suchen
Versuchen Sie nun, nach einer einfachen Kernel-Funktion zu suchen, die Ihnen bekannt ist. Der Benutzerbereich hat
malloc
um Speicher zuzuweisen, während der Kernel seinenkmalloc
hat Funktion, die eine ähnliche Funktionalität bietet. Unten sind allekmalloc
verwandte Funktionen:# 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
[...]Nach Kernelmodul- oder treiberbezogenen Funktionen suchen
Aus der Ausgabe von
available_filter_functions
, können Sie einige Zeilen sehen, die mit Text in Klammern enden, z. B.[kvm_intel]
im Beispiel unten. Diese Funktionen beziehen sich auf das Kernelmodulkvm_intel
, die gerade geladen ist. Sie könnenlsmod
ausführen Befehl zur Überprüfung:# grep kvm verfügbare_filterfunktionen | 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]
pi_wakeup_handler [kvm_intel]
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 16384 1 kvmNur bestimmte Funktionen verfolgen
Um die Verfolgung bestimmter Funktionen oder Muster zu aktivieren, können Sie den
set_ftrace_filter
verwenden Datei, um anzugeben, welche Funktionen aus der obigen Ausgabe Sie verfolgen möchten.
Diese Datei akzeptiert auch den*
Muster, das erweitert wird, um zusätzliche Funktionen mit dem angegebenen Muster aufzunehmen. Als Beispiel verwende ich denext4
Dateisystem auf meinem Rechner. Ich kannext4
angeben bestimmte Kernelfunktionen, die mit den folgenden Befehlen verfolgt werden können:# montieren | grep home
/dev/mapper/fedora-home on /home type ext4 (rw,relatime,seclabel)
# pwd
/sys/kernel/tracing
# cat set_ftrace_filter
#### alle Funktionen aktiviert ####
$
$ 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
[...]Wenn Sie jetzt die Ablaufverfolgungsausgabe sehen, können Sie nur die Funktionen
ext4
sehen bezogen auf Kernelfunktionen, für die Sie zuvor einen Filter gesetzt hatten. Alle anderen Ausgaben werden ignoriert:# cat trace |head -20
## tracer:function
#
# Einträge-im-Puffer/Einträge-geschrieben:3871/3871 #P:8
#
# _-----=> irqs-off
# / _----=> Bedarf-resched
# | | | / _---=> hardirq/softirq
# || / _--=> Preempt-Tiefe
# ||| / delay
# TASK-PID CPU# |||| ZEITSTEMPELFUNKTION
# | | | |||| | |. | ] .... 3308.989552:ext4_file_getattr <-vfs_fstat
cupsd-1066 .... 3308.989553:ext4_getattr <-ext4_file_getattr
CupsD-1066 [004] .... 3308.990097:ext4_file_open <- do_dentry_open
cupsd-1066 .... 3308.990111:ext4_file_getattr <-vfs_fstat
cupsd-1066 .... 3308.990111:ext4_getattr <-ext4_file_getattr
CupsD-1066 [004 ] .... 3308.990122:ext4_llseek <-ksys_lseek
cupsd-1066 [004] .... 3308.990130:ext4_file_read_iter <-new_sync_readFunktionen von der Verfolgung ausschließen
Sie wissen nicht immer, was Sie verfolgen möchten, aber Sie wissen sicherlich, was Sie nicht verfolgen möchten. Dafür gibt es diese Datei mit dem treffenden Namen
set_ftrace_notrace
– Beachten Sie das „Nein“ darin. Sie können Ihr gewünschtes Muster in diese Datei schreiben und das Tracing aktivieren, bei dem alles außer dem erwähnten Muster verfolgt wird. Dies ist oft hilfreich, um allgemeine Funktionen zu entfernen, die unsere Ausgabe überladen:# cat set_ftrace_notrace
#### keine Funktionen deaktiviert ####Gezieltes Tracing
Bisher haben Sie alles verfolgt, was im Kernel passiert ist. Aber das hilft uns nicht, wenn Sie Ereignisse verfolgen möchten, die sich auf einen bestimmten Befehl beziehen. Um dies zu erreichen, können Sie die Ablaufverfolgung bei Bedarf ein- und ausschalten und zwischendurch unseren Befehl Ihrer Wahl ausführen, damit Sie keine zusätzliche Ausgabe in Ihrer Ablaufverfolgungsausgabe erhalten. Sie können die Ablaufverfolgung aktivieren, indem Sie
1
schreiben zutracing_on
, und0
um es auszuschalten:# cat_tracing_on
0
# echo 1> tracing_on
# cat_tracing_on
1
## # Führen Sie einen bestimmten Befehl aus, den wir hier verfolgen möchten ###
# echo 0> tracing_on
# cat tracing_on
0Verfolgung einer bestimmten PID
Wenn Sie Aktivitäten verfolgen möchten, die sich auf einen bestimmten Prozess beziehen, der bereits ausgeführt wird, können Sie diese PID in eine Datei mit dem Namen
set_ftrace_pid
schreiben und aktivieren Sie dann die Ablaufverfolgung. Auf diese Weise ist das Tracing auf diese PID beschränkt, was in manchen Fällen sehr hilfreich ist:# echo $PID > set_ftrace_pid
Schlussfolgerung
Ftrace
ist eine großartige Möglichkeit, mehr über die interne Funktionsweise des Linux-Kernels zu erfahren. Mit etwas Übung können Sie lernen,ftrace
zu optimieren und grenzen Sie Ihre Suche ein. Umftrace
zu verstehen Weitere Einzelheiten und seine fortgeschrittene Verwendung finden Sie in diesen ausgezeichneten Artikeln, die vom Hauptautor vonftrace
geschrieben wurden selbst – Steven Rostedt.
- Debuggen des Linux-Kernels, Teil 1
- Debuggen des Linux-Kernels, Teil 2
- Debuggen des Linux-Kernels, Teil 3