Detectarea Coruperilor de Memorie și a Comportamentului Nedefinit în Rust: Instrumentele Miri, Valgrind și ASan în Rust

Ghid complet de depanare a memoriei în Rust: detectarea comportamentului nedefinit (UB) și a încălcărilor de aliasing cu Miri, sanitizatoare hardware LLVM (AddressSanitizer) și profiling de memorie cu Valgrind.

Sintaxă
cargo miri test | RUSTFLAGS='-Zsanitizer=address' cargo test | valgrind --leak-check=full

Deși Safe Rust garantează absența coruperilor de memorie, proiectele reale din producție depind frecvent de dependențe externe C (via FFI), structuri de date de nivel scăzut optimizate manual sau blocuri de cod unsafe. În aceste situații, un simplu bug de dereferențiere poate introduce Undefined Behavior (UB) extrem de greu de reprodus în testele clasice.

Comunitatea Rust oferă un ecosistem remarcabil de unelte avansate de verificare formală și instrumentare a memoriei.

1. Verificare Formală cu Miri (MIR Interpreter)
# Miri este interpretorul oficial de cod intermediar MIR dezvoltat de echipa Rust.
# El execută codul și testele într-un mediu virtual strict, verificând fiecare acces la memorie!

# Instalarea componentei oficiale:
rustup +nightly component add miri

# Rularea suitei de teste sub supravegherea Miri:
cargo +nightly miri test

# CE DETECTEAZĂ MIRI INSTANTANEU:
# - Încălcări ale modelului Stacked Borrows / Tree Borrows (folosirea unui pointer după ce referința a fost invalidată).
# - Citirea memoriei neinițializate (ex: citirea din spații create cu MaybeUninit nepopulate).
# - Acces în afara limitelor unui bloc alocat (Out-of-bounds pointer arithmetic).
# - Aliniere incorectă a adreselor de memorie (Memory unaligned access).
# - Scurgeri de memorie cauzate de alocări netratate.

2. Sanitizatoare Hardware LLVM: AddressSanitizer (ASan)

Pentru a depana binare compilate nativ la viteza maximă a procesorului (în special când integrăm biblioteci externe C/C++), folosim sanitizatorul nativ LLVM:

# Compilare cu instrumentare de adrese de memorie:
RUSTFLAGS="-Zsanitizer=address" cargo +nightly test --target x86_64-unknown-linux-gnu

# Dacă un pointer C corupe memoria sau depășește un buffer, ASan oprește procesul
# și afișează raportul complet cu linia exactă de cod, octetul depășit și stiva de apel!

3. Profilarea Scurgerilor de Memorie (Memory Leaks) în Rust

Deși Rust previne erorile de tip Dangling Pointer, el nu garantează matematic absența scurgerilor de memorie (ex: două instanțe de Rc> care se referențiază reciproc formează un ciclu permanent pe heap). Pentru auditare:

  • Valgrind Memcheck:
    valgrind --leak-check=full --show-leak-kinds=all ./target/release/my_service
  • DHAT (Dynamic Heap Analysis Tool): Identifică blocurile alocate cel mai frecvent și alocările de durată lungă din aplicație.