Handbuch zur dynamischen Ablaufverfolgung in Solaris

Kapitel 37 Nachträgliche Ablaufverfolgung

Dieses Kapitel befasst sich mit den DTrace-Einrichtungen für die nachträgliche (post mortem) Extraktion und Verarbeitung von kernelinternen Daten der DTrace-Verbraucher. Im Fall eines Systemabsturzes können sich die mit DTrace aufgezeichneten Informationen als Schlüssel zur Ursache des Systemausfalls erweisen. Die DTrace-Daten können aus dem Systemspeicherabzug extrahiert und verarbeitet werden und bei der Aufklärung schwerwiegender Systemstörungen behilflich sein. Die Kombination aus diesen Post-Mortem-Fähigkeiten von DTrace und der Ringpufferrichtlinie (siehe Kapitel 11Puffer und Pufferung) macht DTrace zu einer Art Blackbox, wie wir sie aus der kommerziellen Luftfahrt kennen, für Betriebssysteme.

Zum Extrahieren der DTrace-Daten aus einem bestimmten Speicherabzug führen Sie zunächst den Solaris Modular Debugger mdb(1) auf dem gewünschten Speicherabzug aus. Das MDB-Modul, das die DTrace-Funktion enthält, wird automatisch geladen. Näheres über MDB erfahren Sie in Solaris Modular Debugger Guide .

Anzeigen von DTrace-Verbrauchern

Wenn Sie DTrace-Daten von einem DTrace-Verbraucher extrahieren möchten, müssen Sie zunächst den gewünschten DTrace-Verbraucher angeben. Hierzu führen Sie den MDB-Befehl ::dtrace_state aus:


> ::dtrace_state
    ADDR MINOR     PROC NAME                 FILE
ccaba400     2        - <anonymous>             -
ccab9d80     3 d1d6d7e0 intrstat         cda37078
cbfb56c0     4 d71377f0 dtrace           ceb51bd0
ccabb100     5 d713b0c0 lockstat         ceb51b60
d7ac97c0     6 d713b7e8 dtrace           ceb51ab8

Dieser Befehl gibt eine Tabelle der DTrace-Statusstrukturen aus. Jede Zeile der Tabelle enthält folgende Angaben:

Um weitere Informationen über einen bestimmten DTrace-Verbraucher zu erhalten, übergeben Sie ::ps die Adresse der entsprechenden Prozessstruktur:


> d71377f0::ps
S    PID   PPID   PGID    SID    UID      FLAGS     ADDR NAME
R 100647 100642 100647 100638      0 0x00004008 d71377f0 dtrace

Anzeigen von Ablaufverfolgungsdaten

Nachdem Sie einen Verbraucher bestimmt haben, können Sie die Daten jedes unverbrauchten Puffers abrufen, indem Sie ::dtrace die Adresse der Statusstruktur übergeben. Das folgende Beispiel zeigt die Ausgabe des Befehls ::dtrace auf einer anonymen Aktivierung von syscall:::entry mit der Aktion trace(execname):


> ::dtrace_state
    ADDR MINOR     PROC NAME                 FILE
cbfb7a40     2        - <anonymous>             -

> cbfb7a40::dtrace
CPU     ID                    FUNCTION:NAME
  0    344                resolvepath:entry   init                           
  0     16                      close:entry   init                           
  0    202                      xstat:entry   init                           
  0    202                      xstat:entry   init                           
  0     14                       open:entry   init                           
  0    206                     fxstat:entry   init                           
  0    186                       mmap:entry   init                           
  0    186                       mmap:entry   init                           
  0    186                       mmap:entry   init                           
  0    190                     munmap:entry   init                           
  0    344                resolvepath:entry   init                           
  0    216                    memcntl:entry   init                           
  0     16                      close:entry   init                           
  0    202                      xstat:entry   init                           
  0     14                       open:entry   init                           
  0    206                     fxstat:entry   init                           
  0    186                       mmap:entry   init                           
  0    186                       mmap:entry   init                           
  0    186                       mmap:entry   init                           
  0    190                     munmap:entry   init
...

Der Befehl ::dtrace dcmd behandelt Fehler auf dieselbe Weise wie dtrace(1M). Kommt es während der Ausführung des Verbrauchers zu Auslassungen, Fehlern, spekulativen Auslassungen oder Ähnlichem gibt ::dtrace die gleiche Meldung aus wie dtrace(1M).

::dtrace zeigt die Ereignisse je CPU stets vom ältesten zum neuesten an. Die CPU-Puffer selbst werden in numerischer Reihenfolge wiedergegeben. Sollte es erforderlich sein, die Ereignisse von unterschiedlichen CPUs in sortierter Reihenfolge darzustellen, verfolgen Sie die Variable timestamp.

Durch Angabe der Option -c für ::dtrace lassen sich gezielt nur die Daten einer bestimmten CPU anzeigen:


> cbfb7a40::dtrace -c 1
CPU     ID                    FUNCTION:NAME
  1     14                       open:entry   init
  1    206                     fxstat:entry   init
  1    186                       mmap:entry   init
  1    344                resolvepath:entry   init
  1     16                      close:entry   init
  1    202                      xstat:entry   init
  1    202                      xstat:entry   init
  1     14                       open:entry   init
  1    206                     fxstat:entry   init 
  1    186                       mmap:entry   init  
...

Beachten Sie, dass ::dtrace nur kernelinterne DTrace-Daten verarbeitet. Daten, die aus dem Kernel entnommen und (durch dtrace(1M) oder auf andere Weise) verarbeitet wurden, können nicht mit ::dtrace verarbeitet werden. Um zum Zeitpunkt eines Fehlers stets die größtmögliche Menge an Daten verfügbar zu haben, sollten Sie die Ringpufferrichtlinie verwenden. Weitere Informationen zu Pufferrichtlinien finden Sie in·Kapitel 11Puffer und Pufferung.

Im folgenden Beispiel wird ein sehr kleiner (16 KB) Ringpuffer angelegt und alle Systemaufrufe sowie der Prozess, der sie ausführt, werden aufgezeichnet.


# dtrace -P syscall'{trace(curpsinfo->pr_psargs)}' -b 16k -x bufpolicy=ring
dtrace: description 'syscall:::entry' matched 214 probes

Wenn wir den bei der Ausführung des obigen Befehls erstellten Speicherabzug betrachten, sehen wir eine Ausgabe der Art:


> ::dtrace_state
    ADDR MINOR     PROC NAME                 FILE
cdccd400     3 d15e80a0 dtrace           ced065f0

> cdccd400::dtrace
CPU     ID                    FUNCTION:NAME
  0    139                    getmsg:return   mibiisa -r -p 25216            
  0    138                     getmsg:entry   mibiisa -r -p 25216            
  0    139                    getmsg:return   mibiisa -r -p 25216            
  0    138                     getmsg:entry   mibiisa -r -p 25216            
  0    139                    getmsg:return   mibiisa -r -p 25216            
  0    138                     getmsg:entry   mibiisa -r -p 25216            
  0    139                    getmsg:return   mibiisa -r -p 25216            
  0    138                     getmsg:entry   mibiisa -r -p 25216            
  0    139                    getmsg:return   mibiisa -r -p 25216            
  0    138                     getmsg:entry   mibiisa -r -p 25216            
  0     17                     close:return   mibiisa -r -p 25216            
...
  0     96                      ioctl:entry   mibiisa -r -p 25216            
  0     97                     ioctl:return   mibiisa -r -p 25216            
  0     96                      ioctl:entry   mibiisa -r -p 25216            
  0     97                     ioctl:return   mibiisa -r -p 25216            
  0     96                      ioctl:entry   mibiisa -r -p 25216            
  0     97                     ioctl:return   mibiisa -r -p 25216            
  0     96                      ioctl:entry   mibiisa -r -p 25216            
  0     97                     ioctl:return   mibiisa -r -p 25216            
  0     16                      close:entry   mibiisa -r -p 25216            
  0     17                     close:return   mibiisa -r -p 25216            
  0    124                   lwp_park:entry   mibiisa -r -p 25216            
  1     68                     access:entry   mdb -kw                        
  1     69                    access:return   mdb -kw                        
  1    202                      xstat:entry   mdb -kw                        
  1    203                     xstat:return   mdb -kw                        
  1     14                       open:entry   mdb -kw                        
  1     15                      open:return   mdb -kw                        
  1    206                     fxstat:entry   mdb -kw                        
  1    207                    fxstat:return   mdb -kw                        
  1    186                       mmap:entry   mdb -kw                        
...
  1     13                     write:return   mdb -kw                        
  1     10                       read:entry   mdb -kw                        
  1     11                      read:return   mdb -kw                        
  1     12                      write:entry   mdb -kw                        
  1     13                     write:return   mdb -kw                        
  1     96                      ioctl:entry   mdb -kw                        
  1     97                     ioctl:return   mdb -kw                        
  1    364                    pread64:entry   mdb -kw                        
  1    365                   pread64:return   mdb -kw                        
  1    366                   pwrite64:entry   mdb -kw                        
  1    367                  pwrite64:return   mdb -kw                        
  1    364                    pread64:entry   mdb -kw                        
  1    365                   pread64:return   mdb -kw                        
  1     38                        brk:entry   mdb -kw                        
  1     39                       brk:return   mdb -kw                        
>

Beachten Sie, dass die neuesten Aufzeichnungen der CPU 1 eine Reihe von write(2)-Systemaufrufen durch einen mdb-kw-Prozess enthalten. Dieses Ergebnis steht wahrscheinlich mit dem Grund für die Systemstörung in Zusammenhang, da Benutzer mit mdb(1) und den Optionen -k und -w Daten oder Text des laufenden Kernels modifizieren können. In diesem Fall stellen die DTrace-Daten zumindest eine interessante Spur, möglicherweise aber die Fehlerursache selbst dar.