GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Analysieren Sie den Linux-Kernel mit ftrace

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 tracefs
keine auf /sys/kernel/tracing geben Sie tracefs (rw,relatime,seclabel)
ein

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:

  1. Schreiben Sie in einige spezifische Dateien, um die Ablaufverfolgung zu aktivieren/deaktivieren.
  2. Schreiben Sie in bestimmte Dateien, um Filter zur Feinabstimmung der Ablaufverfolgung festzulegen/zu deaktivieren.
  3. Lesen Sie generierte Ablaufverfolgungsausgaben aus Dateien basierend auf 1 und 2.
  4. Lösche frühere Ausgaben oder Puffer aus Dateien.
  5. 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 mit nop im current_tracer Datei und Ablaufverfolgung wird deaktiviert:

# cat current_tracer
function

# echo nop> current_tracer

# cat current_tracer
nop

Function_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 Sie function_graph zum current_tracer Datei:

# echo function_graph> current_tracer

# cat current_tracer
function_graph

Tracing-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 trace

Zu 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_funktionen

Nach 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 seinen kmalloc hat Funktion, die eine ähnliche Funktionalität bietet. Unten sind alle kmalloc 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 Kernelmodul kvm_intel , die gerade geladen ist. Sie können lsmod 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 kvm

Nur 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 den ext4 Dateisystem auf meinem Rechner. Ich kann ext4 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_read

Funktionen 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 zu tracing_on , und 0 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
0

Verfolgung 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. Um ftrace zu verstehen Weitere Einzelheiten und seine fortgeschrittene Verwendung finden Sie in diesen ausgezeichneten Artikeln, die vom Hauptautor von ftrace geschrieben wurden selbst – Steven Rostedt.

  • Debuggen des Linux-Kernels, Teil 1
  • Debuggen des Linux-Kernels, Teil 2
  • Debuggen des Linux-Kernels, Teil 3

Linux
  1. Planen von Aufgaben mit dem Linux-Cron-Befehl

  2. Planen Sie eine Aufgabe mit dem Linux-Befehl at

  3. Rechnen Sie in der Linux-Shell mit GNU bc

  4. Der Linux-Kernel:Top 5 Innovationen

  5. Der Lebenszyklus des Linux-Kernel-Testens

Lernen Sie Linux mit dem Raspberry Pi

Erste Schritte mit dem i3 Window Manager unter Linux

So überprüfen Sie die Kernel-Version in Linux

Arbeiten mit dem Echtzeit-Kernel für Red Hat Enterprise Linux

So finden Sie Dateien mit dem fd-Befehl in Linux

Sichern Sie Linux mit der Sudoers-Datei