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 oraz close

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"