Dygresja na temat Valgrinda

Valgrind nie służy do wirtualizowania systemów operacyjnych. Ze względu, że jest to bardzo ciekawe narzędzie służące do odpluskwiania programów napisanych pod architekturę 386 pozwolę sobie na jego krótkie omówienie.

Typowe debugery pozwalają na sprawdzenie stanu pamięci programu w momencie gdy pomyłka spowoduje jakiś błąd (dzielenie przez zero, niedozwolona operacja, złe odwołanie do pamięci). Niestety niektóre pomyłki programistyczne powodują błąd zupełnie w innym miejscu programu i czasami dużo później niż błędny kod został wykonany.

Walgrind wykrywa następujące akcje programu, które najczęściej są błędami, a już na pewno złymi praktykami programistycznymi:
Pisanie po pamięci niezaalokowanej przez malloc'a
Wykrywanie czytania z niezainicjowanej pamięci
Gubienie wskaźników do zaalokowanej pamięci
Pisanie/czytanie ze zwolnionej pamięci
Pisanie w nieprawidłowych miejscach na stosie. (np poniżej %esp)
Nakładanie się adresów w standardowej funkcji memcpy

 

Poniżej znajduje się listing programu, który ilustruje niektóre problemy:
#include <stdlib.h>
int main()
{
    int i;
    typedef struct structura_struct {
      int a;
      int b;
    } struktura;
    
    /* pomylkowo alokujemy za malo pamieci */
    struktura *p = malloc(100 * sizeof(struct struktura*));
    
    /* tutaj piszemy po niezaalokowanej pamieci */
    for (i = 0; i < 100; i++) {
	p[i].a = 0;
    }
    
    /* wyszukujemy pierwszy wiekszy od zera b w tablicy p.
     * Przyklad korzystania z niezainicjowanych zmiennych */
    for (i = 0; p[i].b > 0; i++);
    
    /* zgubienie wskaznika do zaalokowanej struktury
     * nigdzie w pamieci nie znajduje sie wskaznik do 
     * tego na co p wskazywalo wczesniej */
    p = 0;
    return 0;
}

Program wykonuje się (niestety) bez błędu, co utrudniałoby debugowanie symptomu błędu w przypadku dopisania dalszego kodu.
A tutaj mamy to co wyświetla valgrind dla niego:
[mateusz@deimos:val]$ valgrind --leak-check=yes ./a.out
==3386== Memcheck, a memory error detector for x86-linux.
==3386== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==3386== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==3386== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==3386== For more details, rerun with: -v
==3386==
==3386== Invalid write of size 4
==3386==    at 0x80483BF: main (in /home/mateusz/tmp/val/a.out)
==3386==  Address 0x1BA571B8 is 0 bytes after a block of size 400 alloc'd
==3386==    at 0x1B904EDD: malloc (vg_replace_malloc.c:131)
==3386==    by 0x804839F: main (in /home/mateusz/tmp/val/a.out)
==3386==
==3386== Conditional jump or move depends on uninitialised value(s)
==3386==    at 0x80483E6: main (in /home/mateusz/tmp/val/a.out)
==3386==
==3386== ERROR SUMMARY: 51 errors from 2 contexts (suppressed: 11 from 1)
==3386== malloc/free: in use at exit: 400 bytes in 1 blocks.
==3386== malloc/free: 1 allocs, 0 frees, 400 bytes allocated.
==3386== For counts of detected errors, rerun with: -v
==3386== searching for pointers to 1 not-freed blocks.
==3386== checked 1443316 bytes.
==3386==
==3386==
==3386== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3386==    at 0x1B904EDD: malloc (vg_replace_malloc.c:131)
==3386==    by 0x804839F: main (in /home/mateusz/tmp/val/a.out)
==3386==
==3386== LEAK SUMMARY:
==3386==    definitely lost: 400 bytes in 1 blocks.
==3386==    possibly lost:   0 bytes in 0 blocks.
==3386==    still reachable: 0 bytes in 0 blocks.
==3386==         suppressed: 0 bytes in 0 blocks.
Valgrind pozwala ponadto na:
Monitorowanie poziomu trafień cache procesora.
Wykrywanie korzystania z fragmentów pamięci przez różne wątki bez użycia prawidłowo muteksów
Monitorowanie poziomu użycia sterty

Z moich obserwacji wynika, że programy uruchamiane pod valgrindem są około 40 razy wolniejsze. Jest to akceptowalny nakład, który zwraca się w postaci szybciej znajdowanych błędów.

Jako ciekawostkę można podać, że KDE 3.0.3 zostało w całości przetestowane za pomocą valgrinda przed wydaniem.

Dynamiczne tłumaczenie kodu.

spis tresci

Porównanie metod.