Einige destruktive Aktionen wirken sich auf das gesamte System aus. Diese Aktionen müssen natürlich mit äußerster Vorsicht eingesetzt werden, da sie jeden Prozess auf dem System und jedes andere implizit oder explizit von den Netzwerkdiensten des betreffenden Systems abhängende System beeinflussen.
void breakpoint(void)
Die Aktion breakpoint() setzt einen Kernel-Haltepunkt, der bewirkt, dass das System anhält und dem Kernel-Debugger die Steuerung übergibt. Der Kernel-Debugger gibt eine Zeichenkette aus, die den DTrace-Prüfpunkt bezeichnet, der die Aktion ausgelöst hat. Nehmen wir beispielsweise Folgendes vor:
# dtrace -w -n clock:entry'{breakpoint()}' dtrace: allowing destructive actions dtrace: description 'clock:entry' matched 1 probe |
Das kann auf einem SPARC-System unter Solaris zur Ausgabe folgender Meldung auf der Konsole führen:
dtrace: breakpoint action at probe fbt:genunix:clock:entry (ecb 30002765700) Type 'go' to resume ok |
Unter Solaris auf einem x86-System wird dies möglicherweise mit folgender Meldung auf der Konsole quittiert:
dtrace: breakpoint action at probe fbt:genunix:clock:entry (ecb d2b97060) stopped at int20+0xb: ret kmdb[0]: |
Bei der Adresse im Anschluss an die Prüfpunktbeschreibung handelt es sich um die Adresse des aktivierenden Steuerblocks (ECB, Enabling Control Block) innerhalb von DTrace. Anhand dieser Adresse lassen sich weitere Informationen über die Prüfpunktaktivierung ermitteln, die die Haltepunktaktion eingeleitet hat.
Ein Fehler im Umgang mit der Aktion breakpoint() kann dazu führen, dass diese wesentlich häufiger als beabsichtigt aufgerufen wird. Dieses Verhalten kann es unter Umständen sogar unmöglich machen, den DTrace-Verbraucher zu beenden, der die Haltepunktaktionen auslöst. In diesem Fall sollten Sie die Kernel-Ganzzahlvariable dtrace_destructive_disallow auf 1 setzen. Diese Einstellung lässt keinerlei destruktive Aktionen auf dem Rechner zu. Greifen Sie auf diese Einstellung jedoch ausschließlich in der beschriebenen Situation zurück.
Das genaue Verfahren zum Festlegen von dtrace_destructive_disallow hängt dabei von dem jeweiligen Kernel-Debugger ab. Wenn Sie mit dem OpenBoot PROM auf einem SPARC-System arbeiten, verwenden Sie w!:
ok 1 dtrace_destructive_disallow w! ok |
Überprüfen Sie mit w?, ob die Variable gesetzt wurde:
ok dtrace_destructive_disallow w? 1 ok |
Geben Sie dann go ein:
ok go |
Für kmdb(1) auf einem x86- oder SPARC-System verwenden Sie den 4-Byte-write-Modifizierer (W) mit der /-Formatierung: x1 dcmd[
kmdb[0]: dtrace_destructive_disallow/W 1 dtrace_destructive_disallow: 0x0 = 0x1 kmdb[0]: |
Fahren Sie fort mit :c:
kadb[0]: :c |
Um anschließend wieder destruktive Aktionen zuzulassen, muss dtrace_destructive_disallow mithilfe von mdb(1) wieder auf 0 zurückgesetzt werden:
# echo "dtrace_destructive_disallow/W 0" | mdb -kw dtrace_destructive_disallow: 0x1 = 0x0 # |
void panic(void)
Wenn die Aktion panic() ausgelöst wird, verursacht sie einen Kernel-Absturz. Sie dient zum Erzwingen eines Systemspeicherabzugs zu einem gezielten Zeitpunkt. Diese Aktion eignet sich zur Untersuchung von Problemen in Kombination mit ring-Pufferung und Post-Mortem-Analyse. Weitere Informationen finden Sie in Kapitel 11Puffer und Pufferung und Kapitel 37Nachträgliche Ablaufverfolgung. Beim Einsatz dieser Aktion wird eine Absturzmeldung mit der Angabe des Prüfpunkts angezeigt, der den Absturz verursacht hat. Beispiel:
panic[cpu0]/thread=30001830b80: dtrace: panic action at probe syscall::mmap:entry (ecb 300000acfc8) 000002a10050b840 dtrace:dtrace_probe+518 (fffe, 0, 1830f88, 1830f88, 30002fb8040, 300000acfc8) %l0-3: 0000000000000000 00000300030e4d80 0000030003418000 00000300018c0800 %l4-7: 000002a10050b980 0000000000000500 0000000000000000 0000000000000502 000002a10050ba30 genunix:dtrace_systrace_syscall32+44 (0, 2000, 5, 80000002, 3, 1898400) %l0-3: 00000300030de730 0000000002200008 00000000000000e0 000000000184d928 %l4-7: 00000300030de000 0000000000000730 0000000000000073 0000000000000010 syncing file systems... 2 done dumping to /dev/dsk/c0t0d0s1, offset 214827008, content: kernel 100% done: 11837 pages dumped, compression ratio 4.66, dump succeeded rebooting... |
syslogd(1M) gibt auch beim Neustart eine Meldung aus.
Jun 10 16:56:31 machine1 savecore: [ID 570001 auth.error] reboot after panic: dtrace: panic action at probe syscall::mmap:entry (ecb 300000acfc8) |
Im Meldungspuffer des Speicherabzugs sind auch der Prüfpunkt und der ECB enthalten, die für die Aktion panic() verantwortlich sind.
void chill(int Nanosekunden)
Die Aktion chill() bewirkt, dass DTrace für die angegebene Dauer in Nanosekunden in den Wartezustand versetzt wird. chill() ist hauptsächlich zur Untersuchung von Problemen geeignet, die mit zeitlichen Abläufen in Zusammenhang stehen könnten. Beispielsweise lassen sich mit dieser Aktion Fenster für Gleichzeitigkeitsbedingungen öffnen oder regelmäßig stattfindende Ereignisse in einen gemeinsamen oder in unterschiedliche Rhythmen schalten. Da Interrupts innerhalb des DTrace-Prüfpunktkontexts deaktiviert sind, führt jede Verwendung von chill() zu Interrupt-Latenz, Scheduling-Latenz und Dispatch-Latenz. chill() verursacht deshalb unter Umständen systemische Effekte und sollte keinesfalls willkürlich eingesetzt werden. Da die Systemtätigkeit von der regelmäßigen Interrupt-Behandlung abhängt, führt DTrace die Aktion chill() keinesfalls länger als 500 Millisekunden pro einsekündigem Intervall auf derselben CPU aus. Wenn das maximale chill()-Intervall überschritten wird, meldet DTrace wie im nächsten Beispiel einen unzulässigen Vorgang:
# dtrace -w -n syscall::open:entry'{chill(500000001)}' dtrace: allowing destructive actions dtrace: description 'syscall::open:entry' matched 1 probe dtrace: 57 errors CPU ID FUNCTION:NAME dtrace: error on enabled probe ID 1 (ID 14: syscall::open:entry): \ illegal operation in action #1 |
Dieser Grenzwert wird selbst dann berücksichtigt, wenn die Zeit auf mehrere chill()-Aufrufe oder mehrere DTrace-Verbraucher eines einzigen Prüfpunkts aufgeteilt ist. Derselbe Fehler würde beispielsweise auch durch den folgenden Befehl generiert werden:
# dtrace -w -n syscall::open:entry'{chill(250000000); chill(250000001);}' |