Handbuch zur dynamischen Ablaufverfolgung in Solaris

Kapitel 19 Der Provider profile

Der Provider profile stellt Prüfpunkte für zeitbasierte Interrupts zur Verfügung, die mit einem festgelegten, angegebenen Intervall ausgelöst werden. Diese nicht verankerten Prüfpunkte sind nicht mit einem bestimmten Punkt in der Ausführung, sondern mit dem asynchronen Interrupt-Ereignis verknüpft. Sie dienen zum Prüfen einiger Aspekte des Systemstatus im Abstand von bestimmten Zeiteinheiten. Auf Grundlage der Messdaten lassen sich Rückschlüsse auf das Systemverhalten ziehen. Bei einer hohen Prüfrate oder einer langen Prüfzeit sind genaue Rückschlüsse möglich. In Verbindung mit DTrace-Aktionen können mit dem Provider profile praktisch alle Aspekte des Systems geprüft werden. So könnten Sie beispielsweise den Zustand des aktuellen Threads, der CPU oder der aktuellen Maschinenanweisung prüfen.


Hinweis –

Thread-lokale Variablen sind für Prüfpunkte aus dem Provider profile nicht erreichbar. Die Verwendung des speziellen Bezeichners self mit einem solchen Prüfpunkt zur Referenzierung einer thread-lokalen Variable generiert keine Ausgabe.


profile-n-Prüfpunkte

Ein profile-n-Prüfpunkt wird in einem festgelegten, regelmäßigen Abstand auf jeder CPU mit einer hohen Interrupt-Ebene ausgelöst. Das Auslösungsintervall des Prüfpunkts wird durch den Wert von n bestimmt: Die Interrupt-Quelle wird n-mal pro Sekunde ausgelöst. Sie können n auch ein optionales Zeitsuffix anfügen. In diesem Fall wird n in der mit dem Suffix angegebenen Zeiteinheit interpretiert. Tabelle 19–1 zeigt die gültigen Suffixe und die von ihnen bezeichneten Einheiten.

Tabelle 19–1 Gültige Zeitsuffixe

Suffix 

Zeiteinheit 

nsec oder ns

Nanosekunden 

usec oder us

Mikrosekunden 

msec oder ms

Millisekunden 

sec oder s

Sekunden 

min oder m

Minuten 

hour oder h

Stunden 

day oder d

Tage 

hz

Hertz (Frequenz pro Sekunde) 

Das nächste Beispiel erzeugt einen Prüfpunkt, der den aktuell laufenden Prozess prüft und mit einer Frequenz von 97 Hertz ausgelöst wird:

#pragma D option quiet

profile-97
/pid != 0/
{
	@proc[pid, execname] = count();
}

END
{
	printf("%-8s %-40s %s\n", "PID", "CMD", "COUNT");
	printa("%-8d %-40s %@d\n", @proc);
}

Wenn der obige Code kurz ausgeführt wird, erhalten wir eine ähnliche Ausgabe wie in folgendem Beispiel:


# dtrace -s ./prof.d
^C
PID      CMD                                      COUNT
223887   sh                                       1
100360   httpd                                    1
100409   mibiisa                                  1
223887   uname                                    1
218848   sh                                       2
218984   adeptedit                                2
100224   nscd                                     3
3        fsflush                                  4
2        pageout                                  6
100372   java                                     7
115279   xterm                                    7
100460   Xsun                                     7
100475   perfbar                                  9
223888   prstat                                   15

Mit dem profile-n-Provider lassen sich auch Informationen über den laufenden Prozess abrufen. Das folgende D-Beispielskript enthält einen profile-Prüfpunkt mit 1.001 Hertz, der zum Abrufen der aktuellen Priorität des angegebenen Prozesses dient:

profile-1001
/pid == $1/
{
	@proc[execname] = lquantize(curlwpsinfo->pr_pri, 0, 100, 10);
}

Um das Beispielskript in Aktion zu sehen, geben Sie die folgenden Befehle in ein Fenster ein:


$ echo $$
12345
$ while true ; do let i=0 ; done

Führen Sie das D-Skript einen kurze Zeit lang in einem anderen Fenster aus. Dabei müssen Sie 12345 mit der PID ersetzen, die Ihr echo-Befehl zurückgegeben hat.


# dtrace -s ./profpri.d 12345
 dtrace: script './profpri.d' matched 1 probe
^C
ksh                                               
           value  ------------- Distribution ------------- count    
             < 0 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@                    7443     
              10 |@@@@@@                                   2235     
              20 |@@@@                                     1679     
              30 |@@@                                      1119     
              40 |@                                        560      
              50 |@                                        554      
              60 |                                         0 

Diese Ausgabe zeigt die Verzerrung der Timesharing-Scheduling-Klasse. Da der Shell-Prozess auf der CPU in einer Warteschleife läuft, wird dessen Priorität vom System stetig herabgesetzt. Wenn der Shell-Prozess seltener laufen würde, käme ihm eine höhere Priorität zuteil. Das Ergebnis sehen Sie, wenn Sie in die wartende Shell Strg-C eingeben und das Skript erneut ausführen:


# dtrace -s ./profpri.d 494621
 dtrace: script './profpri.d' matched 1 probe

Geben Sie nun einige Zeichen in die Shell ein. Nach Beendigung des DTrace-Skripts erhalten Sie eine ähnliche Ausgabe wie in diesem Beispiel:


ksh                                               
           value  ------------- Distribution ------------- count    
              40 |                                         0        
              50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14       
              60 |                                         0

Da der Shell-Prozess nicht in einer Warteschleife auf der CPU gelaufen ist, sondern sich in Erwartung einer Benutzereingabe schlafen gelegt hatte, hat er, als er schließlich ausgeführt wurde, eine wesentlich höhere Priorität erhalten.

tick-n-Prüfpunkte

Wie profile-n-Prüfpunkte werden auch tick-n-Prüfpunkte in einem festgelegten Abstand und mit hoher Interrupt-Ebene ausgelöst. Im Gegensatz zu profile-n-Prüfpunkten, die auf jeder CPU ausgelöst werden, werden tick-n-Prüfpunkte jedoch pro Intervall nur auf einer CPU ausgelöst. Die CPU, um die es sich dabei handelt, kann sich im Lauf der Zeit ändern. Wie bei profile-n-Prüfpunkten wird n standardmäßig als Rate pro Sekunde interpretiert, kann aber auch durch ein optionales Suffix ergänzt werden. tick-n-Prüfpunkte dienen zu verschiedenen Zwecken, wie etwa regelmäßige Ausgaben zu liefern oder regelmäßige Aktionen durchzuführen.

Argumente

Die Argumente für profile-Prüfpunkte lauten:

arg0

Der Programmzähler im Kernel zum Zeitpunkt der Prüfpunktauslösung, oder 0, wenn der aktuelle Prozess zum Zeitpunkt der Prüfpunktauslösung nicht im Kernel ausgeführt wurde 

arg1

Der Programmzähler im Prozess auf Benutzerebene zum Zeitpunkt der Prüfpunktauslösung, oder 0, wenn der aktuelle Prozess zum Zeitpunkt der Prüfpunktauslösung im Kernel ausgeführt wurde 

Wie aus den Beschreibungen hervorgeht, ist arg1 Null, wenn arg0 nicht Null ist, und umgekehrt ist arg1 nicht Null, wenn arg0 Null ist. Folglich können Sie mithilfe von arg0 und arg1 wie in diesem einfachen Beispiel zwischen Benutzer- und Kernelebene unterscheiden:

profile-1ms
{
	@ticks[arg0 ? "kernel" : "user"] = count();
}

Timerauflösung

Der Provider profile stützt sich auf Intervall-Timer mit frei wählbarer Auflösung im Betriebssystem. Auf Architekturen, die keine wirklich auf arbiträren Intervallen beruhenden Interrupts unterstützen, ist die Frequenz durch den Systemuhrtakt begrenzt, die von der Kernelvariable hz vorgegeben ist. Prüfpunkte mit einer höheren Frequenz als hz werden auf diesen Architekturen mehrmals alle 1/hz Sekunden ausgelöst. Beispielsweise wird ein profile-Prüfpunkt mit 1000 Hertz auf einer solchen Architektur, auf der hz auf 100 gesetzt ist, alle zehn Millisekunden zehnmal schnell hintereinander ausgelöst. Auf einer Plattform, die arbiträre Auflösungen unterstützt, würde der profile-Prüfpunkt mit 1000 Hertz genau jede Millisekunde einmal ausgelöst werden.

Die Auflösung einer Architektur lässt sich wie folgt testen:

profile-5000
{
	/*
	 * We divide by 1,000,000 to convert nanoseconds to milliseconds, and
	 * then we take the value mod 10 to get the current millisecond within
	 * a 10 millisecond window.  On platforms that do not support truly
	 * arbitrary resolution profile probes, all of the profile-5000 probes
	 * will fire on roughly the same millisecond.  On platforms that
	 * support a truly arbitrary resolution, the probe firings will be
	 * evenly distributed across the milliseconds.
	 */
	@ms = lquantize((timestamp / 1000000) % 10, 0, 10, 1);
}

tick-1sec
/i++ >= 10/
{
	exit(0);
}

Auf einer Architektur, die profile-Prüfpunkte mit arbiträrer Auflösung unterstützt, ergibt die Ausführung des Beispielskripts eine gleichmäßige Verteilung:


# dtrace -s ./restest.d
 dtrace: script './restest.d' matched 2 probes
CPU     ID                    FUNCTION:NAME
  0  33631                       :tick-1sec 


           value  ------------- Distribution ------------- count    
             < 0 |                                         0        
               0 |@@@                                      10760    
               1 |@@@@                                     10842    
               2 |@@@@                                     10861    
               3 |@@@                                      10820    
               4 |@@@                                      10819    
               5 |@@@                                      10817    
               6 |@@@@                                     10826    
               7 |@@@@                                     10847    
               8 |@@@@                                     10830    
               9 |@@@@                                     10830

Auf einer Architektur, die profile-Prüfpunkte mit arbiträrer Auflösung nicht unterstützt, ergibt die Ausführung des Beispielskripts eine ungleichmäßige Verteilung:


# dtrace -s ./restest.d
 dtrace: script './restest.d' matched 2 probes
 CPU     ID                    FUNCTION:NAME
  0  28321                       :tick-1sec 


           value  ------------- Distribution ------------- count    
               4 |                                         0        
               5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  107864   
               6 |                                         424      
               7 |                                         255      
               8 |                                         496      
               9 |                                         0

Auf diesen Architekturen kann hz zur Verbesserung der effektiven Profilauflösung unter /etc/system manuell angepasst werden.

Derzeit unterstützen alle Varianten von UltraSPARC (sun4u) profile-Prüfpunkte mit arbiträrer Auflösung. Auch zahlreiche Varianten der x86-Architektur (i86pc) bieten Unterstützung für profile-Prüfpunkte mit frei wählbarer Auflösung, einige ältere Varianten jedoch nicht.

Prüfpunkterzeugung

Im Gegensatz zu anderen Providern erzeugt der Provider profile die Prüfpunkte dynamisch auf Bedarfsbasis. Der gewünschte profile-Prüfpunkt scheint in einer Auflistung aller Prüfpunkte (z. B. mit dtrace -l -P profile) möglicherweise nicht auf, wird aber erzeugt, wenn er ausdrücklich aktiviert wird.

Auf Architekturen, die profile-Prüfpunkte mit frei wählbarer Auflösung unterstützen, würde die Maschine durch ein zu kurzes Intervall kontinuierlich zeitbasierte Interrupts abfangen und einen Denial-of-Service-Fehler auslösen. Um dies zu verhindern, lehnt der Provider profile kommentarlos die Erzeugung von Prüfpunkten ab, die ein Intervall von weniger als 200 Mikrosekunden bewirken würden.

Stabilität

Der Provider profile beschreibt die verschiedenen Stabilitäten anhand des DTrace-Stabilitätsmechanismus gemäß der folgenden Tabelle. Weitere Informationen zum Stabilitätsmechanismus finden Sie in Kapitel 39Stabilität.

Element 

Namensstabilität 

Datenstabilität 

Abhängigkeitsklasse 

Provider 

Evolving 

Evolving 

Common

Modul 

Unstable 

Unstable 

Unknown 

Funktion 

Private 

Private 

Unknown 

Name 

Evolving 

Evolving 

Common

Argumente 

Evolving 

Evolving 

Common