Was dieses Skript macht ist nichts anderes als sich zu jedem Lock der geschlossen wird den Stacktrace zu merken und sobald wir an den Punkt kommen an dem das Deadlock auftritt uns zu zeigen wer gerade das Lock hält das uns am weitergehen hindert. Das ganze ist ein unglaublicher Speicherfresser (ich muss dazu sagen das die jeweiligen Stacktraces einfach nur abnorm waren) da ich hier Speculations verwende (siehe letzter Eintrag ;) ) und DTrace bereinigt den Speicher nur in bestimmten Intervallen, was in bei der Menge an Locks einfach zu langsam war. Außerdem hat man nur eine begrenzte Anzahl an Speculations zur Verfügung. Aber DTrace wär nicht das was es ist wenn man das nicht auch "aushebeln" könnte ;)
nspec
dient dazu die Anzahl der möglichen Speculations hochzusetzen und cleanrate
bestimmt die Frequenz der Garbagecollection, mit -b
schrauben wir den Gesamtpuffer auf 128MB hoch.Also, ohne weitere Umschweife: der Star des gestrigen Tages!
#!/usr/sbin/dtrace -b 128m -x nspec=20 -x cleanrate=101 -s
pid$target::deadlockgoeshere:entry
{
self->traceme = 1;
}
pid$target::deadlockgoeshere:return
/self->traceme/
{
self->traceme = 0;
}
pid$target::pthread_mutex_lock:entry
/spec[arg0] == 0/
{
spec[arg0] = speculation();
speculate(spec[arg0]);
ustack();
}
pid$target::pthread_mutex_lock:entry
/spec[arg0] && self->traceme/
{
commit(spec[arg0]);
spec[arg0] = 0;
}
pid$target::pthread_mutex_lock:entry
/spec[arg0] && self->traceme == 0/
{
discard(spec[arg0]);
spec[arg0] = 0;
}
pid$target::pthread_mutex_unlock:entry
{
discard(spec[arg0]);
spec[arg0] = 0;
}
Keine Kommentare:
Kommentar veröffentlichen