Zasada Działania Detektorów Wycieku Pamięci

Jak działają detektory wycieku pamięci? Jakie są podstawowe pojęcia w ogóle? Może wziąć C++ jako język, aby to wyjaśnić.

Author: Benjamin Gruenbaum, 2015-02-11

3 answers

Istnieje kilka różnych sposobów działania detektorów nieszczelności. Możesz zastąpić implementację malloc i free takimi, które mogą śledzić więcej informacji podczas alokacji i nie dotyczą wydajności. Jest to podobne do tego, jak dmalloc Działa. Ogólnie rzecz biorąc, każdy adres, który jest malloc'ed, ale nie free'd jest wyciekły.

Podstawowa implementacja jest całkiem prosta. Po prostu utrzymujesz tabelę wyszukiwania KAŻDEGO przydziału i jego numer linii i usuwasz wejście po uwolnieniu. Następnie po zakończeniu programu można wyświetlić listę wszystkich wycieków pamięci. Najtrudniejsze jest określenie, kiedy i gdzie przydział powinien zostać uwolniony. Jest to jeszcze trudniejsze, gdy istnieje wiele wskaźników do tego samego adresu.

W praktyce prawdopodobnie potrzebujesz czegoś więcej niż tylko numeru pojedynczej linii, ale raczej śledzenia stosu utraconych przydziałów.

Innym podejściem jest sposób działania valgrind , który implementuje całą maszynę wirtualną, aby zachować śledzenie adresów i odniesień do pamięci oraz związanych z nimi księgowości. Podejście valgrind jest znacznie droższe, ale również bardziej skuteczne, ponieważ może również informować o innych typach błędów pamięci, takich jak odczyty lub zapisy poza granicami.

Valgrind zasadniczo instrumentuje podstawowe instrukcje i może śledzić, kiedy dany adres pamięci nie ma więcej odniesień. Może to zrobić, śledząc przypisania adresów, a więc może powiedzieć nie tylko, że kawałek pamięci został utracony, ale dokładnie kiedy stało się stracone.

C++ utrudnia pracę obu typów detektorów nieszczelności, ponieważ dodaje operatory new i delete. Technicznie new może być zupełnie innym źródłem pamięci niż malloc. Jednak w praktyce wiele rzeczywistych implementacji C++ po prostu używa malloc do implementacji new lub ma opcję użycia malloc zamiast alternatywnego podejścia.

Również języki wyższego poziomu, takie jak C++ , mają zwykle alternatywne sposoby wyższego poziomu przydzielanie pamięci jak std::vector lub std::list. Podstawowy wykrywacz nieszczelności raportowałby potencjalnie wiele przydziałów dokonanych przez tryby wyższego poziomu oddzielnie. To znacznie mniej przydatne niż stwierdzenie, że cały kontener został zgubiony.

 59
Author: b4hand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-11 16:36:15

Oto opublikowany dokument techniczny o tym, jak działa nasze narzędzie CheckPointer.

Zasadniczo śledzi życie wszystkich wartości (sterty i stosu) i ich wielkości zgodnie z ich typami określonymi przez język. Pozwala to CheckPointer na znajdowanie nie tylko wycieków, ale także dostępu poza tablicami, nawet dla tablic w stosie, czego valgrind nie zrobi.

W szczególności analizuje kod źródłowy, aby znaleźć wszystkie zastosowania wskaźnika. (Jest to dość zadanie tylko przez siebie).

Śledzi metadane wskaźnika dla każdego wskaźnika, składające się z

  • odniesienie do metadanych obiektu dla obiektu przydzielonego stercie lub globalnej lub lokalnej zmiennej lub funkcji wskazywanej przez wskaźnik i
  • zakres adresów (pod) obiektu obiektu, do którego wskaźnik może obecnie uzyskać dostęp. Może być mniejszy niż zakres adresów całego obiektu; np. jeśli przyjmiesz adres elementu struct, kod źródłowy będzie tylko Zezwalaj na dostęp do tego elementu podczas używania wskaźnika wynikowego.

Śledzi również rodzaj i położenie każdego obiektu, tzn. czy jest to funkcja, globalna, lokalna lub lokalna zmienna wątku, pamięć przydzielona stercie lub literalna stała ciągu znaków:

  • zakres adresów obiektu, do którego można bezpiecznie uzyskać dostęp, oraz
  • dla każdego wskaźnika przechowywanego w obiekcie lub zmiennej przydzielonej stercie, odniesienie do metadanych wskaźnika dla tego wskaźnika.

Wszystkie to śledzenie jest realizowane przez przekształcenie oryginalnego źródła programu w program, który robi to, co robi oryginalny program i przeplata różne procedury sprawdzania lub aktualizacji metadanych. Powstały program jest kompilowany i uruchamiany. Jeśli sprawdzenie metadanych nie powiedzie się w czasie wykonywania, backtrace jest dostarczane z raportem typu błędu (nieprawidłowy wskaźnik, wskaźnik poza poprawnymi granicami,...)

 19
Author: Ira Baxter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-13 15:38:56

To jest oznaczone C i C++ i żaden system operacyjny nie jest wymieniony. Ta odpowiedź jest dla systemu Windows.

C

Windows ma pojęcie pamięci wirtualnej. Każda pamięć, którą proces może uzyskać, jest pamięcią wirtualną. Odbywa się to za pomocą VirtualAlloc () [MSDN] . Możesz sobie wyobrazić, że wykrywacz nieszczelności umieszcza punkt przerwania na tej funkcji i kiedy jest wywoływany, pobiera callstack i gdzieś go zapisuje. Następnie może to zrobić podobnie dla VirtualFree () [MSDN] .

Różnica może być następnie zidentyfikowany i pokazany wraz z zapisanymi połączeniami.

C++

C++ ma inną koncepcję: pobiera duże bloki 64kb, które otrzymuje z VirtualAlloc () i dzieli je na mniejsze kawałki, zwane stertą. C++ heap manager pochodzi od firmy Microsoft i oferuje nowe metody HeapAlloc () [MSDN] i HeapFree () [MSDN] .

Wtedy możesz zrobić to samo, co wcześniej, ale w rzeczywistości ta funkcja jest już wbudowana. Microsoft ' s GFlags[MSDN] narzędzie może włączyć śledzenie:

Zrzut ekranu: GFlags włączony dla Notatnika

W tym przypadku zapisuje do 50 MB informacji o callstack dla wywołań menedżera sterty C++.

Ponieważ ustawienia te mogą być również włączone przez rejestr systemu Windows, wykrywacz wycieku pamięci może z niego łatwo skorzystać.

Pojęcie ogólne

Jak widać, ogólna koncepcja polega na śledzeniu alokacji i dealokacji, porównywaniu ich i pokazywaniu połączeń różnicy.

 8
Author: Thomas Weller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-11 11:58:54