2015-12-02 5 views
5

Sto creando una libreria che ha troppo codice per darla qui.Come cercare un errore "all'indirizzo non valido indicato nella riga successiva"

Il mio problema è un errore di segmentazione, che Valgrind analizzare come:

Vai a l'indirizzo non valido dichiarato nella riga successiva
a 0x72612F656D6F682F: ???
a [...] (chiamata stack)

Grazie a this question, credo che è perché ho una pila di corruzione da qualche parte.

La mia domanda è: come trovarlo?
Ho provato a utilizzare GDB, ma l'errore di segmentazione sembra non essere nella stessa posizione. GDB mi dice che si trova sulla prima riga di una funzione mentre Valgrind dice che è la chiamata di questa funzione che fa difetto di segmentazione.

+1

La risoluzione dei problemi relativi a UB non è affatto divertente e l'ordinamento di corruzione heap/stack può essere davvero doloroso. Non conosco un metodo metodico perfetto per farlo - solo un processo di restrizione dei sospetti (ad esempio: omettere temporaneamente sezioni di codice da elaborare, eliminare i sospetti come un investigatore). Quello che ho trovato nel corso degli anni è che ottengo sempre meno di questi - sono più facili da prevenire che scoprire a posteriori. Asserire le assunzioni liberamente, e specialmente intorno al codice pericoloso, può essere utile. Fare test rigorosi ogni volta che coinvolgi costrutti di basso livello può essere un risparmiatore di vita. –

+1

Il rigore della procedura di test dovrebbe in genere ridimensionarsi con la quantità di codice di basso livello che stai scrivendo, ad esempio se stai scrivendo un contenitore di basso livello o un allocatore di memoria, che richiede un sacco di test delle unità. Ad ogni modo - temo che non sia così utile per il problema immediato - forse qualcuno ha un ottimo modo per eseguire il debug di questi. –

+1

@Ike Right, era un contenitore sperimentale che stava scavalcando i dati sul mio stack ... Grazie per il consiglio. – Aracthor

risposta

4

Se il problema è ripetibile, è possibile utilizzare una tecnica simile a this answer per impostare un punto di controllo sulla posizione dell'indirizzo di ritorno, e fare fermare GDB sull'istruzione immediatamente successiva a quella che lo corrompe.

+0

@Aracthor E il punto della risposta è quello di dirti esattamente come scoprirlo. Tu * sai * dove è memorizzato l'indirizzo di ritorno, e tu * sai * è corretto all'ingresso nella funzione. Quindi imposta il punto di controllo e GDB si fermerà quando quella posizione verrà sovrascritta. –

+0

Ma qual è la * posizione dell'indirizzo di ritorno * che dovrei impostare come punto di controllo? – Aracthor

+0

Se si dispone di una build non ottimizzata, e se si è in 'x86_64', quando si entra nella funzione (prolog della funzione passata), l'indirizzo di ritorno verrà memorizzato in' $ rbp [1] '. Se esegui 'x/2a $ rbp', dovresti vedere il precedente $ rbp e l'indirizzo del chiamante della tua funzione. Se hai una build ottimizzata, dovrai 'disassemblare' la funzione per trovare dove viene memorizzato l'indirizzo di ritorno. –

Problemi correlati