Jak mogę znaleźć wyciek pamięci w uruchomionym procesie?


19

Czy istnieje sposób, aby wykryć wyciek pamięci w uruchomionym procesie? Mogę użyć Valgrind do wykrywania wycieków pamięci przed rozpoczęciem procesu. Mogę użyć GDB, aby dołączyć go do uruchomionego procesu. Jak mogę debugować wycieki pamięci z uruchomionego procesu?


Valgrind jest bardzo przydatny, nazwałbym to nawet intuicyjnym.
user400344

Odpowiedzi:


13

Oto prawie gwarancja kroków, aby dowiedzieć się, kto przecieka pamięć:

  1. Znajdź PID procesu, który powoduje wyciek pamięci.

    ps -aux
  2. przechwyć /proc/PID/smapsi zapisz w jakimś pliku, takim jak BeforeMemInc.txt.

  3. poczekaj, aż pamięć się zwiększy.
  4. złap ponownie /proc/PID/smapsi zapisz goafterMemInc.txt
  5. znajdź różnicę między pierwszym smapsa drugim smaps, np. za pomocą

    diff -u beforeMemInc.txt afterMemInc.txt

  6. zanotuj zakres adresów, w których pamięć została zwiększona, na przykład:

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
  7. użyj GDB, aby zrzucić pamięć przy uruchomionym procesie lub uzyskać zrzut rdzeniowy za pomocą gcore -o process

  8. Użyłem gdb podczas uruchamiania procesu, aby zrzucić pamięć do jakiegoś pliku.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. teraz użyj stringspolecenia lub, hexdump -Caby wydrukowaćdump_outputfile.dump

    strings outputfile.dump
  10. Otrzymasz czytelną formę, w której możesz zlokalizować te ciągi w kodzie źródłowym.

  11. Przeanalizuj swoje źródło, aby znaleźć wyciek.


12

Myślę, że memleax jest dokładnie tym, czego chcesz.

Debuguje wyciek pamięci uruchomionego procesu, dołączając go, bez ponownej kompilacji programu lub ponownego uruchamiania procesu docelowego. Jest to bardzo wygodne i odpowiednie dla środowiska produkcyjnego.

Działa na GNU / Linux i FreeBSD.

UWAGA: Jestem autorem, wszelkie sugestie są mile widziane

== EDYCJA ==

Piszę kolejne narzędzie libleak , które przechwytuje funkcje pamięci przez LD_PRELOAD.

Nie ma również potrzeby modyfikowania programu docelowego. Chociaż musisz ponownie uruchomić postęp z LD_PRELOAD, możesz włączyć / wyłączyć wykrywanie podczas działania.

Wpływ na wydajność jest znacznie mniejszy, ponieważ nie ma pułapki na sygnał.

W porównaniu z podobnymi narzędziami (takimi jak mtrace), drukuje pełny stos wywołań w podejrzanym punkcie przecieku pamięci.


1
Gwarantuję memleax jako bardzo przydatne narzędzie do monitorowania wszelkich oczywistych wycieków. Podsumowania wyników są zaskakująco skuteczne . Prawie tak, jakbym je napisał, gdybym miał moc przetwarzania, aby zrobić to ręcznie. Dzięki za to
patrz


0

Myślę, że bez wsparcia monitorowania alokacji po uruchomieniu programu bezpośrednio w kodzie źródłowym nie masz szczęścia. Oto dwa powody, dla których mogę wymyślić:

  • Kontrolery sterty są inicjowane po uruchomieniu programu. Niektóre oferują możliwość dostosowania dokładnego czasu, ale zmienne środowiskowe, które je uruchamiają, muszą być ustawione podczas uruchamiania programu. Wynika to z tego, że pilnują, aby upewnić się, że każda alokacja ma odpowiednią dezalokację, i w przeciwnym razie przegapiliby niektóre.
  • Sprawdzanie stosu zwykle wymaga podwyższonych uprawnień lub haków, które zapewnia system operacyjny. Jeśli te zaczepy nie zostaną dostarczone w momencie uruchomienia programu, kontrolery sterty nie będą mogły ich wykorzystać. Nie sądzę, aby systemy operacyjne zapewniały te uprawnienia po uruchomieniu danego programu.

Jeśli jednak program działa na maszynie wirtualnej, środowisko to może obsługiwać monitorowanie przydziałów. Wiem, że Java ma kilka narzędzi do monitorowania alokacji i czyszczenia pamięci (takich jak visualVM ), które dołączają się do uruchomionych programów lub maszyn wirtualnych.


0

IBM Purify jest prawdopodobnie najstarszym i najbardziej zaawansowanym narzędziem ze wszystkich. Będzie to oznaczać numer linii w kodzie, który powoduje wyciek pamięci.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.