Ein einfaches Beispiel: Wir interessieren uns für alles was im Kernel während des Öffnens einer Datei passiert, allerdings wollen wir das Ergebnis nur wissen wenn das Öffnen fehlschlägt. Das macht folgendes D-Script:
#!/usr/sbin/dtrace -s
syscall::open:entry
/execname == "a.out"/ {
self->spec = speculation();
speculate(self->spec);
printf("%s",copyinstr(arg0));
}
fbt:::
/self->spec/ {
speculate(self->spec);
}
syscall::open:return
/self->spec && arg1 == -1/ {
commit(self->spec);
}
syscall::open:return
/self->spec/ {
discard(self->spec);
}
Ok, gehen wir das Ganze mal durch:
self->spec = speculation();
legt threadlokal einen Puffer unter dem Namen spec
an. Eine Speculation ist also nichts anderes als ein Puffer in dem wir Messwerte zwischenspeichern und darauf warten ob sie wichtig werden.Um in einer Klausel das "Aufzeichnen" zu starten reicht ein
speculate(self->spec)
, alle darauf folgenden Messwerte wandern in unseren Puffer. Tritt ein Ereignis ein das unseren Werten im Puffer Bedeutung verleiht können wir sie mit commit(self->spec);
ausgeben oder im gegenteiligen Fall mit discard(self->spec);
verwerfen.ACHTUNG: Puffer zu füllen ist eine kostspielige Angelegenheit, denkt daran das wir uns hier im Kernelkontext befinden. Also solltet ihr Daten die ihr nicht mehr braucht auch sofort verwerfen. Wachsen eure Puffer ungehindert weiter wird die DTrace VM euch einen Strich durch die Rechnung ziehen und selbst anfangen Daten zu verwerfen damit ihr das System nicht in den Abgrund zieht. Des weiteren ist der Trace den ich oben beschrieben habe auch schon recht "brutal" da der Puffer mit einem kompletten
fbt
Messdatensatz befüllt wird. Das bremst open-systemcalls übel aus, also: HANDLE WITH CARE!