Dienstag, 30. März 2010

Spekulatives Tracen mit DTrace

Spekulieren ist ja nicht erst seit der "Finanzkrise" der letzte Schrei, auch wir Programmierer stehen hin und wieder mal vor der Situation das wir Kram anhäufen von dem wir nicht wissen ob wir ihn später noch gebrauchen können. Besonders beim Debuggen fallen oft Daten an bei denen wir erst wissen ob sie interessant sind wenn wir schon bis zum Hals in Messwerten stecken. Wie also die Spreu vom Weizen trennen? DTrace hat ein Feature das leider viel zu wenig Beachtung bekommt: Speculations.

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!

Keine Kommentare: