Skip to content

Analisi Statica e Dinamica

Trovare i bug manualmente è costoso e prono ad errori. L’industria moderna si affida a potenti strumenti di analisi per scovare i difetti nel codice prima che raggiungano il cliente.

Questi strumenti si dividono in due grandi famiglie.

L’Analisi Statica esamina il codice sorgente senza mai eseguirlo. Si comporta come un compilatore estremamente pedante, leggendo il codice, costruendo alberi decisionali e deducendo matematicamente i possibili valori delle variabili per trovare falle di sicurezza, variabili non inizializzate o dereferenziazioni di puntatori NULL.

  • Vantaggi: È velocissima. Si avvia ad ogni salvataggio del file o durante la compilazione.
  • Svantaggi: È matematicamente impossibile dedurre il comportamento esatto di tutti i software staticamente. Pertanto gli analizzatori statici generano spesso Falsi Positivi (segnalano come bug del codice perfettamente sano) oppure Falsi Negativi (non vedono bug gravi che invece ci sono).

L’Analisi Dinamica valuta il comportamento del software mentre è in esecuzione. Funziona strumentando l’eseguibile: il compilatore (o un tool virtuale) inietta istruzioni invisibili o hook per monitorare l’accesso in memoria in tempo reale.

  • Vantaggi: Il tasso di falsi positivi è bassissimo. Se uno strumento dinamico segnala un errore, quell’errore è reale e va corretto subito!
  • Svantaggi: Rallenta pesantemente le prestazioni del programma. Richiede una “Copertura del Codice” (Code Coverage) altissima: se il bug dinamico si nasconde all’interno di un blocco if che i tuoi test non attivano, l’analizzatore non lo vedrà.

Valgrind è un classico strumento di analisi dinamica che esegue il tuo programma all’interno di una macchina virtuale, controllando ogni accesso alla memoria. È molto potente e non richiede la ricompilazione speciale del codice (basta usare -g), ma rallenta il programma enormemente (fino a 20-30 volte).

Il re incontrastato dell’analisi dinamica per il C è AddressSanitizer (ASan), sviluppato originariamente da Google e integrato nativamente in GCC, Clang e Visual Studio. Inserisce controlli extra durante la compilazione.

ASan rileva istantaneamente a runtime:

  • Use-after-free: dereferenziazione di un puntatore già liberato con free().
  • Buffer overflow: scrittura oltre la fine di un array nell’Heap o nello Stack.
  • Memory Leaks: memoria allocata con malloc che il programmatore si è dimenticato di liberare prima dell’uscita.

Per abilitarlo su Linux/Mac, passa il flag -fsanitize=address:

Terminal window
gcc -g3 -fsanitize=address mio_codice.c -o mio_programma

Se il programma contiene un leak o un overflow, ASan stamperà un report spettacolare con stack trace completo indicando la riga esatta!

💻 Esercizio Pratico (Simulazione di AddressSanitizer)

Section titled “💻 Esercizio Pratico (Simulazione di AddressSanitizer)”

Immaginiamo di eseguire questo codice compilato con -fsanitize=address. Attualmente accede a un indice fuori limite (buffer overflow). Correggi l’accesso in modo che il ciclo for scriva solo negli indici validi (0 a 4) per risolvere il “crash di ASan”.