Cosa fare con un errore di segmentazione 11
Per qualche motivo, ho deciso di costruire un prodotto usando plain C. Se l’obiettivo era l’efficienza del codice, era un disastro. Ma come strumento per la crescita personale, penso di aver imparato molto di più sulla programmazione nel processo.
Ad esempio, ora so più precisamente perché un dizionario python e una lista si comportano in modo diverso e cosa significa veramente “passare per riferimento.”
Tuttavia, se ci fosse una barriera che mi farebbe non voler mai tornare a C, sarebbe il temuto” Segmentation Fault 11″, seguito da vicino da ” Abort Trap 6.”
Questi due errori si verificano durante il runtime, rendendoli difficili da eseguire il debug. XCode, Eclipse o altri strumenti di debug sono davvero utili, ma ho imparato che è molto più importante imparare quali sono queste cose e trovare procedure per affrontare il processo di debug. Questo è solo i miei appunti sui miei errori comuni. Spero di rendere questo un elenco di risoluzione dei problemi per chiunque abbia i propri problemi. Voglio almeno coprire i miei stupidi problemi, in modo da poterti concentrare sui veri problemi di codifica.
Un errore di segmentazione significa che il tuo programma ha cercato di accedere a qualcosa che non avrebbe dovuto. E ‘ parte del problema. Ci sono molte ragioni per cui un programma può accedere a cose che non dovrebbe, ma il codice compilato praticamente dice solo “## # @^*&!” invece. Se ci pensate, non si vorrebbe avere a spiegare a qualcuno perché li frugando in un punto sensibile ti fa impazzire. Vuoi solo che smettano di farlo. Fortunatamente, i computer sono entrambi stupidi e sorprendentemente pazienti dopo circa 75 anni di ingegneria. Continueranno a inviare errori Seg, ma (di solito) non smetteranno di essere amici dopo che accadrà la 1000a volta.
Che cos’è Abort Trap?
Non è molto diverso. Da qualche parte, il tuo computer si è detto di interrompere il programma. Di nuovo, non molto utile. Tuttavia, di solito si verifica quando si tenta di fare qualcosa di simile di accesso string
di due char stringa "nw"
o non allocare abbastanza memoria char string
per una stringa o un array come "way"
.
Cosa si deve fare con un guasto Seg?
I tutorial che ho letto tendono a concentrarsi sull’utilizzo di strumenti di debug come lldb, gdb e così via. Va tutto bene e dandy. Sì, dovresti eseguire prima gcc -g
e poilldb executable_name
e poirun -flag1 -flag2
per vedere se questo ti aiuta a capirlo. Ma a volte non c’è alcun aiuto. Ho una lista di cose da controllare però.
- Verificare che le variabili globali del programma necessarie abbiano valori. Questo è successo soprattutto perché avevo creato flag che riempivano un sacco di valori che dovevano essere impostati prima dell’esecuzione. Tuttavia, cosa succede se non mettono nulla? Seg Guasto 11! Ci sono state un certo numero di volte in cui ho *pensato* vars sono stati impostati quando non lo erano e che ha fatto per bug impegnativi. Meglio ancora, cerca di mantenere i globali al limite in modo che siano più facili da tracciare.
- malloc è sia tuo amico che tuo nemico. Soprattutto con le voci degli utenti, può essere molto difficile allocare memoria e quindi copiare, concatenare e fare qualsiasi altra cosa lungo la strada. Conoscere bene questo comando e come funziona. E non dimenticare di
free()
la memoria quando hai finito! - utilizzare
char var
per determinare la dimensione di un carattere* per l’allocazione della memoria. La maggior parte del problema che avevo coinvolto l’assegnazione di variabili per accettare eventualmente una stringa. Ho visto altri consigli, ma se è una stringa con cui stai lavorando, penso chestrlen()
abbia funzionato nel modo più coerente. È necessario il +1 per\0
(null) per terminare la stringa alla fine. - usa
int arr) +1)]
per array di altri tipi. È un modo strano di fare le cose, ma è quello che ottieni con un linguaggio di basso livello. -
\0
rappresenta null e terminerà un array. Può essere utile quando si tenta di prevenire problemi di overflow del buffer. - Cerca di usare le costanti definite il più possibile. Ogni volta che sei in grado di definire le cose alla precompilazione, ti farà risparmiare tempo di debug in seguito.
- Capire a cosa servono i file di intestazione. Molti dei tutorial ti diranno cosa contiene un file di intestazione, ma non è sempre chiaro a cosa servono. I file di intestazione vengono acquisiti in fase di pre-compilazione e forniscono un riepilogo delle variabili e delle funzioni disponibili per il programma *prima della compilazione*. Ciò significa che il .i file c inclusi nel programma saranno in grado di accedere a queste funzioni, a condizione che
#include <headerfile.h>
venga aggiunto al file. Una buona convenzione è quello di creare un .h file ogni volta che si crea un . - La maggior parte dei cicli for va così:
for (int i=0; i < stop; i++)
Un modo semplice per avere una trappola di interruzione è mettere un ≤ davanti astop
. - Mantieni i tuoi problemi contenuti. Cerca di fare in modo che ogni file faccia alcune cose discrete e nient’altro. Se si deve cacciare attraverso diversi file più e circa, si può fare trovare i vostri problemi di guasto seg davvero difficile.
- La matematica del computer è difficile. Non è proprio, ma le piccole cose causano grossi problemi.
char variable
ad esempio significa un array contenente due elementi, ma poiché gli indici iniziano da 0, significa che puoi solo salire al numero 1. - Stampa le stringhe di formato come il tipo giusto. Fortunatamente, questo di solito viene catturato in fase di compilazione, ma può ancora causare problemi. Assicurati che il tuo carattere di formato
%{whatever}
si adatti a qualsiasi variabile che vuoi inserire.
Questo è tutto quello che ho per ora. Spero che le mie miserie ti abbiano salvato qualche mal di testa lungo la strada! Se tutto il resto fallisce, ora ho una lista di cose da controllare prima di tirare fuori i capelli!