QNA > C > Come Capire Cosa Sta Causando Un Errore Sigsegv Nel Mio Codice

Come capire cosa sta causando un errore SIGSEGV nel mio codice

SIGSEGV (abbreviato da segmentation violation) viene inviato al processo colpevole.

Cause

Le condizioni in cui si verificano le violazioni di segmentazione e come si manifestano sono specifiche dell'hardware e del sistema operativo:

Il diverso hardware solleva guasti diversi per determinate condizioni, e diversi sistemi operativi convertono questi in segnali diversi che vengono passati ai processi.
La causa prossima è una violazione di accesso alla memoria, mentre la causa sottostante è generalmente un bug software di qualche tipo.

Determinare la causa principale - il debugging del bug - può essere semplice in alcuni casi, dove il programma causerà costantemente un errore di segmentazione (ad esempio, dereferenziando un puntatore nullo), mentre in altri casi il bug può essere difficile da riprodurre e dipendere dall'allocazione della memoria ad ogni esecuzione (ad es, dereferenziazione di un puntatore dangling).
Quelle che seguono sono alcune cause tipiche di un errore di segmentazione:

  • Dereferenziazione di puntatori NULL - questo è un caso speciale per l'hardware di gestione della memoria
  • Tentativo di accedere ad un indirizzo di memoria inesistente (al di fuori dello spazio di indirizzi del processo's address space)
  • Tentativo di accedere alla memoria di cui il programma non ha diritti (come le strutture del kernel nel contesto del processo)
  • Tentativo di scrivere memoria di sola lettura (come il segmento di codice)

Questi a loro volta sono spesso causati da errori di programmazione che risultano in un accesso alla memoria non valido:

  • Dereferenziazione o assegnazione ad un puntatore non inizializzato (puntatore selvaggio, che punta ad un indirizzo di memoria casuale)
  • Dereferenziazione o assegnazione ad un puntatore liberato (dangling pointer, che punta alla memoria che è stata liberata/deallocata/cancellata)
  • Un buffer overflow
  • Un stack overflow
  • Tentativo di eseguire un programma che non compila correttamente. (Alcuni compilatori produrranno un file eseguibile nonostante la presenza di errori di compilazione.)

Nel codice C, i difetti di segmentazione si verificano più spesso a causa di errori nell'uso dei puntatori, in particolare nell'allocazione dinamica della memoria C. Dereferenziare un puntatore nullo risulterà sempre in un errore di segmentazione, ma i puntatori selvaggi e i puntatori dangling puntano alla memoria che può o non può esistere, e può o non può essere leggibile o scrivibile, e quindi può portare a bug transitori. Per esempio:
char *p1 = NULL; // Puntatore nullo
char *p2; // Puntatore selvaggio: non inizializzato affatto.
char *p3 = malloc(10 * sizeof(char)); // Puntatore inizializzato alla memoria allocata
// (assumendo che malloc non sia fallito)

free(p3); // p3 è ora un puntatore dangling, poiché la memoria è stata liberata


Ora, dereferenziare una di queste variabili potrebbe causare un errore di segmentazione: dereferenziare il puntatore nullo generalmente causerà un segfault, mentre leggere dal puntatore selvaggio può invece risultare in dati casuali ma nessun segfault, e leggere dal puntatore penzolante può risultare in dati validi per un po', e poi in dati casuali quando viene sovrascritto.

Di Ticon Lamoree

La fotocamera dell'iPhone X è meglio di una fotocamera mirrorless? :: Quale telefono dovrei comprare: IPhone 5S o Moto X Play?
Link utili