Mam dużą aplikację, która się składa 4 bibliotek tworzonych w ramach projektu, plus X zależności.
Problem polega na tym, że z aplikacji powoli wyciekają File Descriptors.
Po 7 godzinach automatycznych testów funkcjonalnych, testy nie przechodzą, bo program osiągnął limit file descriptorów (1024 - co dziwne limit pochodzi z jednej z bibliotek nie z systemu).
Dzięki lsof
i pokrewnych wiem, że problem leży z połączaniem https do konkretnego serwera.
Dowcip polega na tym, że z logów wynika iż wszystko jest ładnie sprzątane i wycieku nie powinno być.
To sugeruje, że wyciek jest z innej biblioteki (tego projektu, albo innej zależności).
Mimo, że wiem, które połączenie jest problemem nie jestem w stanie odtworzyć tego lokalnie.
Teraz pytanie jak ustalić winnego, skoro logi wszystkich rozgrzeszają, a sam odtworzyć tego nie mogę?
googlanie skierowało mnie na narzędzie dtrace
http://dtrace.org/ (problem widzę na platformie OS X)
To jest spora maszyneria z wykorzystująca język d
.
Chcę napisać skrypt, który będzie łapał backtrace dla konkretnego procesu, gdy file descriptor jest otwierany (być może też ostatni zapis i odczyt).
W przypadku kiedy file descriptor jest zamykany to wtedy usuwałbym ten wpis z agregatora.
Ogólnie już widzę, że na 100% da się to zrobić, ale mam problem by połączyć to do kupy.
Nie wiem, jak konkretnie (widzę jakieś ogólniki):
- usnąć pojedynczego wpis z agregatora
- jak odfiltrować się do konkretnego procesu
- pozyskać backtrace
- jaki powinienem wyglądać filtr dla
open
orazclose
Choć może lepiej skorzystać z jakiegoś filtru tcp? W jedum z przykłądów znalazłem coś takiego:
#!/usr/sbin/dtrace -s
# contents of tcpnmap.d
#pragma D option quiet
dtrace:::BEGIN
{
printf("Tracing for possible nmap scans... Hit Ctrl-C to end.\n");
}
tcp:::accept-refused
{
@num["TCP_connect()_scan", args[2]->ip_daddr] = count();
}
tcp:::receive
/args[4]->tcp_flags == 0/
{
@num["TCP_null_scan", args[2]->ip_saddr] = count();
}
tcp:::receive
/args[4]->tcp_flags == (TH_URG|TH_PUSH|TH_FIN)/
{
@num["TCP_Xmas_scan", args[2]->ip_saddr] = count();
}
dtrace:::END
{
printf("Possible scan events:\n\n");
printf(" %-24s %-28s %8s\n", "TYPE", "HOST", "COUNT");
printa(" %-24s %-28s %@8d\n", @num);
}
Jestem dopiero na początku drogi (dopiero parę godzin na tym siedzę), ale może ktoś ma większe doświadczenie z dtrace
(np @hauleth ) i będzie mi w stanie z tym pomóc.
To samo na SO
Jeśli sam dojdę do tego co i jak to się pochwalę.
Jeśli ktoś widzi inny sposób na ustalenie kodu, który powoduje wyciek to chętnie skorzystam.
PS. Za bardzo nie wiedziałem jak sklasyfikować tego posta, wiec wylądowało tutaj. W sumie równie dobrze może być to: "Nietuzinkowe tematy" "inne języki oprogramowania"
dtruss
?dtruss
to skrypt dodtrace
. Próbowałem go użyć z parametrem-s
, ale wtedy nie łapie tego co jest mi potrzebne.