 Autor: [Adam Nadolny](/autorzy/adam-nadolny) Ekspert DevOps i infrastruktury · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  Valgrind — wykrywanie wycieków pamięci

# Valgrind — wykrywanie wycieków pamięci i błędów w aplikacjach

Opublikowano: 10 kwietnia 2026 · Kategoria: VPS

Serwer restartuje się co kilka dni przez OOM Killer. Aplikacja C++ działa poprawnie przez godziny, po czym nagle pada z segfault. Natywne rozszerzenie PHP wycieka pamięć pod obciążeniem. To są typowe scenariusze, gdzie `Valgrind` jest nieocenionym narzędziem — dynamicznie analizuje każdą operację na pamięci i wskazuje dokładnie gdzie i dlaczego coś się dzieje źle, z pełnym stack trace. Bez konieczności modyfikacji kodu źródłowego.

## Instalacja i Memcheck — podstawowe użycie

\# Ubuntu/Debian
sudo apt install valgrind kcachegrind massif-visualizer -y

# Podstawowe uruchomienie (Memcheck — domyślne narzędzie)
valgrind ./myapp

# Pełne opcje dla maksymalnej detekcji błędów
valgrind \\
  --leak-check=full \\
  --show-leak-kinds=all \\
  --track-origins=yes \\
  --verbose \\
  --log-file=valgrind-report.txt \\
  ./myapp arg1 arg2

# Wyjaśnienie flag:
# --leak-check=full      — pokazuj każdy blok wycieku osobno
# --show-leak-kinds=all  — wszystkie kategorie (def/indir/poss/reach)
# --track-origins=yes    — śledź skąd pochodzi niezainicjalizowana wartość
# --log-file=            — zapis do pliku (raport może być duży)
# --error-exitcode=1     — return 1 gdy są błędy (dobre dla CI)

# PHP z Memcheck (test rozszerzeń natywnych)
valgrind --leak-check=full \\
  /usr/bin/php -c /etc/php/8.2/cli/php.ini \\
  -d extension=myext.so \\
  test.php

## Interpretacja raportu Memcheck

\==12345== HEAP SUMMARY:
==12345==     in use at exit: 4,096 bytes in 1 blocks
==12345==   total heap usage: 150 allocs, 149 frees, 45,678 bytes allocated
==12345==
==12345== 4,096 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345==    at 0x483B7F3: malloc (in /usr/lib/x86\_64-linux-gnu/valgrind/vgpreload\_memcheck.so)
==12345==    by 0x10921F: create\_buffer (myapp.c:42)
==12345==    by 0x109345: process\_request (myapp.c:87)
==12345==    by 0x1094A2: main (myapp.c:124)
==12345==
==12345== LEAK SUMMARY:
==12345==    definitely lost: 4,096 bytes in 1 blocks   <-- PROBLEM
==12345==    indirectly lost: 0 bytes in 0 blocks
==12345==      possibly lost: 256 bytes in 2 blocks
==12345==    still reachable: 2,048 bytes in 5 blocks   <-- zazwyczaj OK
==12345==         suppressed: 0 bytes in 0 blocks
==12345==
==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

# Kategorie LEAK SUMMARY:
# definitely lost  — wskaźnik całkowicie utracony. MUSISZ naprawić.
# indirectly lost  — przez inne "definitely lost". Naprawa tamtych = fix tu.
# possibly lost    — Valgrind nie jest pewny. Może być celowe.
# still reachable  — program zakończył się nie zwalniając. Często OK (globals).
# suppressed       — wyciszony przez plik .supp (znane false positives bibliotek)

## Suppression files — eliminacja false positives

Biblioteki systemowe (OpenSSL, glibc, Python runtime) często wykazują "wycieki" które są celowe lub nieistotne. Pliki suppressions pozwalają wyciszyć znane false positives.

\# Generuj plik suppressions na podstawie bieżącego raportu
valgrind --leak-check=full --gen-suppressions=all ./myapp 2>all-suppressions.txt

# Edytuj i zachowaj interesujące suppressions
# Przykład pliku myapp.supp:
# {
#   openssl\_init\_suppression
#   Memcheck:Leak
#   match-leak-kinds: reachable
#   fun:malloc
#   fun:CRYPTO\_malloc
#   fun:sk\_reserve
#   obj:\*libssl.so\*
# }

# Użyj pliku suppressions
valgrind --suppressions=myapp.supp --leak-check=full ./myapp

# Gotowe pliki supp dla popularnych bibliotek:
# /usr/lib/valgrind/default.supp (domyślnie załadowany)
# Dla Pythona: valgrind --suppressions=${PREFIX}/lib/python\*/test/valgrind-python.supp python3 test.py

## Callgrind — profilowanie cache i funkcji

\# Uruchom z narzędziem Callgrind
valgrind --tool=callgrind ./myapp
# Wynik: callgrind.out.12345 (numer PID)

# Opcje szczegółowe
valgrind \\
  --tool=callgrind \\
  --callgrind-out-file=myapp.callgrind \\
  --cache-sim=yes \\
  --branch-sim=yes \\
  --instr-atstart=no \\  # nie zbieraj od startu (użyj CALLGRIND\_START\_INSTRUMENTATION w kodzie)
  ./myapp

# Szybki tekstowy raport
callgrind\_annotate callgrind.out.12345 | head -80

# Wizualizacja w KCachegrind (GUI)
kcachegrind callgrind.out.12345 &

# KCachegrind pokazuje:
# - Flat Profile: ile instrukcji/cykli kosztuje każda funkcja
# - Call Graph: drzewo wywołań z kosztami
# - Source Annotation: linia po linii z kosztami
# - Cache simulation: L1/L2/LL miss rates per function

## Massif — profilowanie sterty (heap profiler)

Massif śledzi użycie pamięci sterty w czasie — pozwala zobaczyć kiedy i dlaczego aplikacja alokuje coraz więcej pamięci. Niezbędny gdy aplikacja nie wycieka (Memcheck czysto) ale ciągle rośnie.

\# Uruchom Massif
valgrind --tool=massif ./myapp
# Wynik: massif.out.12345

# Tekstowy raport (ms\_print)
ms\_print massif.out.12345 | head -100

# Output pokazuje "snapshots" użycia pamięci:
# --------------------------------------------------------------------------------
#    n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
# --------------------------------------------------------------------------------
#    0              0                0               0             0            0
#   10      1,234,567        2,345,678       2,300,000        45,678            0
#   20      2,345,678        4,567,890       4,500,000        67,890            0
# \[peak snapshot pokazuje najwyższy punkt użycia pamięci\]

# Szczegóły szczytu użycia (kto alokował)
ms\_print massif.out.12345 | grep -A 30 "peak"

# GUI: massif-visualizer (Ubuntu)
massif-visualizer massif.out.12345 &

# Profilowanie stosu (stack) oprócz sterty
valgrind --tool=massif --stacks=yes ./myapp

## Porównanie Valgrind z AddressSanitizer i innymi narzędziami

Narzędzie

Narzut

Rekompilacja

Wykrywa

Najlepsze do

Valgrind Memcheck

10-50x wolniej

Nie (działa na binarce)

Wycieki, invalid reads, UAF, uninitialized

Binaries bez źródeł, skomplikowane wycieki

AddressSanitizer (ASan)

2-3x wolniej

Tak (-fsanitize=address)

Buffer overflow, UAF, double-free

Dev z kompilacją, szybkie wykrywanie

LeakSanitizer (LSan)

2x wolniej

Tak (-fsanitize=leak)

Tylko wycieki pamięci

Szybka detekcja wycieków w CI

MemorySanitizer (MSan)

3-5x wolniej

Tak (-fsanitize=memory)

Uninitialized reads (tylko)

Wykrywanie niezainicjalizowanych wartości

Valgrind Callgrind

10-50x wolniej

Nie

Cache misses, call graph, hot functions

Cache analysis, call graph visualization

heaptrack

3-5x wolniej

Nie (LD\_PRELOAD)

Heap allocations, wycieki

Nowoczesna alternatywa dla Massif

## Najczęstsze pytania

Co to jest Valgrind i jakie błędy wykrywa? +

Valgrind to framework do dynamicznej analizy programów, składający się z wielu narzędzi. Memcheck (domyślny) wykrywa: memory leaks (wyciek pamięci — brak free/delete), invalid reads i writes (dostęp poza zakresem bufora), use-after-free (dostęp do zwolnionej pamięci), double-free (dwukrotne zwolnienie), uninitialized values (użycie niezainicjalizowanej pamięci). Jest niezastąpiony przy debugowaniu programów C/C++ oraz natywnych rozszerzeń Python, Ruby, PHP i Node.js.

Czym różni się Valgrind od AddressSanitizer? +

Valgrind działa bez rekompilacji — uruchamia program na wirtualnej maszynie (narzut 10-50x, średnio 20x). AddressSanitizer (ASan) to flaga kompilatora (-fsanitize=address) — wymaga rekompilacji ale ma znacznie mniejszy narzut (2-3x). ASan jest szybszy i wykrywa błędy w locie, Valgrind jest dokładniejszy w analizie wycieków. Wybór: Valgrind gdy nie masz źródeł lub dla bibliotek, ASan gdy kompilujesz sam i potrzebujesz szybszej analizy.

Co to jest Callgrind i jak go używać? +

Callgrind to narzędzie profilowania cache i wywołań funkcji wchodzące w skład Valgrind. Symuluje CPU i zlicza instrukcje, dostępy do cache L1/L2/LLC dla każdej funkcji. Uruchomienie: valgrind --tool=callgrind ./myapp, wyniki w callgrind.out.PID. Do wizualizacji użyj KCachegrind (Linux) lub QCachegrind (macOS/Windows) — pokazuje call graph, hot paths i cache miss rates per function.

Jak czytać raport Valgrind Memcheck? +

Raport Valgrind kończy się podsumowaniem LEAK SUMMARY z kategoriami: "definitely lost" (wyciek — wskaźnik utracony, pamięć nieosiągalna), "indirectly lost" (wyciek przez referencję od directly lost), "possibly lost" (wskaźnik wewnętrzny, może być celowy), "still reachable" (pamięć dostępna w momencie zakończenia — często bufor globalny, nie zawsze błąd). Priorytet naprawy: definitely lost > indirectly lost > possibly lost. Still reachable można zazwyczaj ignorować.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z dużą ilością RAM — Valgrind potrzebuje 3-5x więcej pamięci niż testowana aplikacja

RAM intensive

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

ProSerwer.pl

Polski VPS z root access do instalacji Valgrind i KCachegrind

Root VPS

[Aktywuj rabat →](/out/proserwer-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/proserwer)

Mikr.us

Budżetowy VPS do nauki i testów Valgrind na własnych aplikacjach

Dev/Learn

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

## Powiązane strony

-   [perf — profilowanie CPU i analiza wydajności](/baza-wiedzy/perf-profiling-cpu)
-   [strace i ltrace — diagnostyka procesów Linux](/baza-wiedzy/strace-debugging-linux)
-   [Linux kernel — tuning wydajności dla serwerów](/baza-wiedzy/linux-performance-tuning-kernel)
-   [Wszystkie artykuły](/baza-wiedzy/)