(1)
Esiste un concetto di "test della morte" , in cui un difetto di il codice causerebbe la chiusura del processo.
Per eseguire tale test di morte, il cablaggio di test deve avviare un processo separato che eseguirà il pezzo di codice. La condizione di terminazione viene quindi presa come criterio di superamento o fallimento.
Ovviamente, non tutte le unità di testing framework supportano questo tipo di test.
(2)
Alcuni compilatori C ++ forniscono opzioni che inseriranno ulteriori controlli nel codice generato.
Esempi di ciò che faranno queste opzioni:
- Assicurati che quando la chiamata alla funzione ritorna, il suo indirizzo di ritorno abbia lo stesso valore (in pila) come quando è stata appena inserita la chiamata alla funzione.
- Assicurarsi che i buffer di memoria allocati dinamicamente non vengano sovrascritti prima dell'inizio o dopo la sua fine.
(3)
Infine ci sono anche strumenti di copertura del codice e strumentazione come valgrind.
Se esistono alcuni modelli di dati che causeranno un arresto anomalo in modo affidabile (ma solo che non si conosce quale), la fuzzing può essere una strategia molto efficace per scoprire tali schemi di dati che causano arresti anomali. Per esempio. afl-fuzz .
Se utilizzare strumenti aggiuntivi è fuori questione, forse puoi modificare il codice tu stesso per renderlo più "testabile". Un esempio è la sostituzione degli accessi agli array con un sovraccarico dell'operatore C ++ che esegue il controllo dei limiti dell'indice dell'array. I dettagli dipendono dal tipo di codice interrogato.