Valgrind - Valgrind

Valgrind
Valgrind logo.png
Pierwotni autorzy Julian Seward
Deweloper (y) Zespół programistów Valgrind
Wersja stabilna 3.16.1 (22 czerwca 2020 r . ; 6 miesięcy temu ) [±]  ( 22.06.2020 )
Magazyn Edytuj to w Wikidata
System operacyjny Linux
macOS
Solaris
Android
Rodzaj Profiler , debugger pamięci
Licencja Powszechna Licencja Publiczna GNU
Stronie internetowej www .valgrind .org

Valgrind ( / V ć l ɡ R ɪ n d / ) jest narzędziem do programowania dla usuwania błędów pamięci , szczelności pamięć wykrywania i profilowania .

Valgrind został pierwotnie zaprojektowany jako bezpłatne narzędzie do debugowania pamięci dla systemu Linux na platformie x86 , ale od tego czasu ewoluował, aby stać się ogólną strukturą do tworzenia narzędzi do analizy dynamicznej, takich jak kontrolery i profilery.

Nazwa Valgrind nawiązuje do głównego wejścia do Valhalli z mitologii nordyckiej. Podczas tworzenia (przed wydaniem) projekt nosił nazwę Heimdall ; jednak nazwa byłaby w konflikcie z pakietem bezpieczeństwa.

Przegląd

Valgrind jest w istocie maszyną wirtualną wykorzystującą techniki kompilacji just-in-time (JIT), w tym rekompilację dynamiczną . Nic z oryginalnego programu nigdy nie jest uruchamiane bezpośrednio na procesorze hosta . Zamiast tego Valgrind najpierw tłumaczy program na tymczasową, prostszą formę o nazwie Intermediate Representation (IR), która jest niezależną od procesora formą opartą na SSA . Po konwersji narzędzie (patrz poniżej) może wykonać dowolne przekształcenia w podczerwieni, zanim Valgrind przetłumaczy IR z powrotem na kod maszynowy i pozwoli procesorowi hostowi go uruchomić. Valgrind rekompiluje kod binarny, aby działał na hostach i docelowych (lub symulowanych) procesorach o tej samej architekturze. Zawiera również kod pośredniczący GDB umożliwiający debugowanie programu docelowego, gdy jest on uruchamiany w Valgrind, z „poleceniami monitora”, które umożliwiają odpytywanie narzędzia Valgrind o różne informacje.

Podczas tych transformacji następuje znaczna utrata wydajności (i zazwyczaj kodu wstawianego przez narzędzie); zwykle kod jest uruchamiany z Valgrind, a narzędzie „none” (które nie robi nic z IR) działa z 20% do 25% szybkości normalnego programu.

Przybory

Memcheck

Istnieje wiele narzędzi zawartych w Valgrind (i kilka zewnętrznych). Domyślnym (i najczęściej używanym) narzędziem jest Memcheck . Memcheck wstawia dodatkowy kod oprzyrządowania wokół prawie wszystkich instrukcji, który śledzi poprawność (cała nieprzydzielona pamięć zaczyna się jako nieważna lub „niezdefiniowana”, dopóki nie zostanie zainicjalizowana w stan deterministyczny, prawdopodobnie z innej pamięci) i adresowalności (czy adres pamięci w punkty pytanie przydzielonego, nie uwolnił bloku pamięci) są zawarte w tak zwanych bitów V i bity a odpowiednio. Gdy dane są przenoszone lub manipulowane, kod instrumentacji śledzi bity A i V, więc są one zawsze poprawne na poziomie jednego bitu.

Ponadto Memcheck zastępuje standardowy alokator pamięci C swoją własną implementacją, która obejmuje również osłony pamięci wokół wszystkich przydzielonych bloków (z bitami A ustawionymi jako „nieważne”). Ta funkcja umożliwia Memcheck wykrywanie błędów typu off-by-one, w przypadku których program odczytuje lub zapisuje poza przydzielonym blokiem o niewielką wartość. Problemy, które Memcheck może wykryć i przed którymi ostrzega, obejmują:

  • Korzystanie z niezainicjowanej pamięci
  • Czytanie / zapisywanie pamięci po jej zakończeniu free d
  • Czytanie / zapisywanie końca malloc bloków „d”
  • Wycieki pamięci

Ceną tego jest utrata wydajności. Programy działające pod kontrolą Memcheck zwykle działają 20–30 razy wolniej niż programy działające poza Valgrind i zużywają więcej pamięci (na alokację nakładana jest kara za pamięć). Dlatego niewielu programistów uruchamia swój kod pod Memcheck (lub jakimkolwiek innym narzędziem Valgrind) przez cały czas. Najczęściej używają takich narzędzi do wyśledzenia określonego błędu lub do sprawdzenia, czy w kodzie nie ma ukrytych błędów (takich, jakie może wykryć Memcheck).

Inne narzędzia

Oprócz Memcheck Valgrind ma kilka innych narzędzi:

  • Brak , uruchamia kod na maszynie wirtualnej bez wykonywania żadnej analizy, dzięki czemu ma najmniejszy możliwy narzut procesora i pamięci ze wszystkich narzędzi. Ponieważ sam valgrind zapewnia śledzenie wstecz od błędu segmentacji , narzędzie none zapewnia to śledzenie przy minimalnym narzucie.
  • Addrcheck , podobny do Memcheck , ale ze znacznie mniejszym obciążeniem procesora i pamięci, dzięki czemu wyłapuje mniej rodzajów błędów. Addrcheck został usunięty w wersji 3.2.0.
  • Massif , profiler sterty . Oddzielny wizualizator masywu GUI wizualizuje dane wyjściowe z Massif.
  • Helgrind i DRD wykrywają warunki wyścigu w kodzie wielowątkowym
  • Cachegrind , profiler pamięci podręcznej . Oddzielny graficzny interfejs użytkownika KCacheGrind wizualizuje dane wyjściowe z Cachegrind.
  • Callgrind , analizator callgraph stworzony przez Josefa Weidendorfera, został dodany do Valgrind w wersji 3.2.0. KCacheGrind może wizualizować dane wyjściowe z Callgrind.
  • DHAT , narzędzie do dynamicznej analizy sterty, które analizuje ilość przydzielonej pamięci i jak długo, a także wzorce wykorzystania pamięci.
  • exp-sgcheck (o nazwie exp-ptrcheck przed wersją 3.7), eksperymentalne narzędzie do znajdowania błędów przepełnienia stosu i globalnej tablicy, których Memcheck nie może znaleźć. Niektóre kody powodują fałszywe alarmy z tego narzędzia.
  • exp-bbv , symulator wydajności, który ekstrapoluje wydajność z małego zestawu próbek.

Dostępnych jest również kilka narzędzi opracowanych zewnętrznie. Jednym z takich narzędzi jest ThreadSanitizer, kolejny wykrywacz warunków wyścigu .

Obsługiwane platformy

Od wersji 3.4.0 Valgrind obsługuje Linuksa na x86 , x86-64 i PowerPC . Wsparcie dla OS X zostało dodane w wersji 3.5.0. Wsparcie dla Linuksa na ARMv7 (używane na przykład w niektórych smartfonach ) zostało dodane w wersji 3.6.0. Wsparcie dla Solaris zostało dodane w wersji 3.11.0. Istnieją nieoficjalne porty na inne platformy podobne do UNIX (takie jak FreeBSD , OpenBSD i NetBSD ). Od wersji 3.7.0 dodano obsługę platformy ARM / Android .

Od wersji 3.9.0 istnieje wsparcie dla Linuksa na MIPS64 little i big endian, dla MIPS DSP ASE na MIPS32, dla instrukcji dziesiętnych s390x, instrukcji POWER8 ( Power ISA 2.07 ), instrukcji Intel AVX2 , rozszerzeń synchronizacji transakcyjnej Intel , RTM i HLE oraz początkowa obsługa sprzętowej pamięci transakcyjnej przy zasilaniu.

Historia i rozwój

Jej nazwa pochodzi od głównego wejścia do Valhalli w mitologii nordyckiej .

Oryginalnym autorem Valgrind jest Julian Seward , który w 2006 roku zdobył nagrodę Google-O'Reilly Open Source Award za swoją pracę nad Valgrind.

Kilka innych osób również miało znaczący wkład, w tym Cerion Armor-Brown, Jeremy Fitzhardinge, Tom Hughes, Nicholas Nethercote, Paul Mackerras, Dirk Mueller, Bart Van Assche, Josef Weidendorfer i Robert Walsh.

Jest używany przez wiele projektów opartych na systemie Linux.

Ograniczenia Memcheck

Oprócz spadku wydajności, ważnym ograniczeniem Memcheck jest jego niezdolność do wykrycia wszystkich przypadków błędów granic podczas korzystania z danych statycznych lub przydzielonych na stosie. Poniższy kod przejdzie narzędzie Memcheck w Valgrind bez incydentów, mimo że zawiera błędy opisane w komentarzach:

  int Static[5];
  
  int func(void)
  {
    int Stack[5];
  
    Static[5] = 0;  /* Error - Static[0] to Static[4] exist, Static[5] is out of bounds */
    Stack [5] = 0;  /* Error - Stack[0] to Stack[4] exist, Stack[5] is out of bounds */
    
    return 0;
  }

Eksperymentalne narzędzie valgrind exp-sgcheck zostało napisane w celu rozwiązania tego ograniczenia w Memcheck. Wykryje błędy przepełnienia tablicy, pod warunkiem, że pierwszy dostęp do tablicy znajduje się w granicach tablicy. Zwróć uwagę, że exp-sgcheck nie wykryje przepełnienia tablicy w powyższym kodzie, ponieważ pierwszy dostęp do tablicy jest poza zakresem, ale wykryje błąd przepełnienia tablicy w poniższym kodzie.

  void func(void)
  {
    int i, Stack[5];

    for (i = 0; i <= 5; i++)
        Stack [i] = 0;        /* Within bounds for i=0..4, out of bounds error when i=5 */
  }

Brak możliwości wykrycia wszystkich błędów związanych z dostępem do danych alokowanych na stosie jest szczególnie godny uwagi, ponieważ niektóre typy błędów stosu sprawiają, że oprogramowanie jest podatne na klasyczny exploit służący do niszczenia stosu .

Zobacz też

Uwagi

Bibliografia

Linki zewnętrzne