Plus, Il programma viene eseguito su un dispositivo braccio su cui è in esecuzione Linux, posso stampare informazioni sullo stack e registrare i valori nel gestore sig-seg che assegno. Il problema è che non posso aggiungere l'opzione -g al file sorgente, poiché il bug potrebbe non riprodursi a causa del downgrade delle prestazioni.Come sapere quale indirizzo illegale accede al programma quando si verifica un errore di segmentazione
risposta
La compilazione con l'opzione -g
su gcc
fa non causa un "downgrade delle prestazioni". Tutto ciò che fa è far includere i simboli di debugging; lo non influisce sull'ottimizzazione o sulla generazione del codice.
Se si installa il gestore SIGSEGV
utilizzando il sa_sigaction
membro del sigaction
struct passato a sigaction()
, poi la si_addr
membro della struttura siginfo_t
passata al gestore contiene l'indirizzo ha provocato l'errore.
Ho riscontrato problemi in cui un segfault causato dalla scrittura su un puntatore non inizializzato appariva e spariva a seconda che io usassi -g, o quale livello -o avevo . Ha a che fare con ciò che la memoria è dove. Allo stesso modo, l'ho avuto dove l'aggiunta o l'eliminazione di un printf ha fatto apparire l'errore. i segfaults in C possono essere bastardi astuti. –
Questo sembra funzionare http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
// info->si_addr is the illegal address
}
'info-> si_addr' è l'indirizzo di memoria guasto. Come indicato nel link che hai fornito, l'indirizzo al momento in cui il segnale è stato sollevato può essere recuperato da "void * ptr". Vedere la mia risposta qui per il codice che ho usato con ARM - http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/1925461#1925461 – jschmier
tendo a usare valgrind
che indica perdite e difetti di accesso alla memoria.
valgrind è per X86, AMD64 e PPC - l'interrogante è in esecuzione su ARM. Tuttavia sono piacevolmente sorpreso di leggere che il supporto ARM è in corso. – crazyscot
@crazyscot Ho davvero mancato la parte "arm" della domanda.Ma bello sapere che valgrind sta per supportare questa architettura;) – ereOn
Se si è preoccupati di utilizzare -g sul binario che si carica sul dispositivo, è possibile utilizzare gdbserver sul dispositivo ARM con una versione ridotta del file eseguibile ed eseguire arm-gdb sul computer di sviluppo con la versione non estinta dell'eseguibile. La versione ridotta e la versione unstripped devono corrispondere fino a farlo, in modo da fare questo:
# You may add your own optimization flags
arm-gcc -g program.c -o program.debug
arm-strip --strip-debug program.debug -o program
# or
arm-strip --strip-unneeded program.debug -o program
Avrete bisogno di leggere la documentazione gdb e gdbserver per capire come usarli. Non è così difficile, ma non è così lucido come potrebbe essere. Principalmente è molto facile dire a gdb di fare qualcosa che finisce per pensare che volevi fare localmente, quindi uscirà dalla modalità di debug remoto.
Si potrebbe anche voler utilizzare la funzione backtrace() se disponibile, che fornirà lo stack di chiamate al momento dello schianto. Questo può essere usato per scaricare lo stack come accade in un linguaggio di programmazione di alto livello quando un programma C ottiene un errore di segmentazione, errore del bus o altro errore di violazione della memoria.
backtrace() è disponibile sia su Linux e Mac OS X
Se l'opzione -g fa l'errore scompare, quindi sapere dove si blocca è improbabile che sia utile in ogni caso. Probabilmente sta scrivendo su un puntatore non inizializzato nella funzione A, e quindi la funzione B tenta di utilizzare legittimamente quella memoria e muore. Gli errori di memoria sono un dolore.
- 1. Errore di segmentazione quando si chiama clock()
- 2. Come accedere ai registri di controllo cr0, cr2, cr3 da un programma? Errore di segmentazione
- 3. Come si accede al valore di una query SQL count() in un programma Java
- 4. Errore di segmentazione quando si utilizza regexec/strtok_r in C
- 5. Un errore di segmentazione Python?
- 6. Errore 500.19 in IIS7 quando si verifica un errore
- 7. Errore di segmentazione in PHP?
- 8. compilazione personalizzato messaggio di errore quando sottotipo definito si accede
- 9. errore di analisi xml sul carattere illegale
- 10. Come si accede al controller di visualizzazione di un super?
- 11. Come sapere quando si verifica una perdita di dati su un cluster elasticsearch
- 12. errore WEBrick :: HTTPStatus :: LengthRequired quando si accede creare Procedimento controllore
- 13. ftell (stdin) provoca un errore cercare illegale
- 14. Errore di segmentazione Git: 11
- 15. Invia un'e-mail quando si verifica un errore
- 16. Errore di segmentazione C++
- 17. Che cosa significa cin fare quando si verifica un errore
- 18. Errore di segmentazione Sprintf
- 19. pthread (errore di segmentazione)
- 20. Come si accede al DisplayNameFor in un modello nidificato
- 21. Come sapere quale versione di cuDNN si dovrebbe usare?
- 22. Come sapere quale funzione si chiama un altro
- 23. errore di segmentazione: 11
- 24. Dichiarazione di causa variabile errore di segmentazione
- 25. Errore di sintassi: return illegale in JavaScript
- 26. Come si accede alle informazioni di errore del database quando si utilizzano Rails e Postgres
- 27. Errore di segmentazione che si verifica nella valutazione dell'espressione postfissa utilizzando lo stack
- 28. Errore di segmentazione (core scaricato)
- 29. C++ di base colpa programma di segmentazione
- 30. Errore di segmentazione quando si chiama un lib di Rust con Ruby FFI
Almeno con GCC è possibile aggiungere -g senza disabilitare l'ottimizzazione. E su obiettivi ELF, GCC inserisce le informazioni di debug in sezioni separate, in modo che non vengano nemmeno caricate dal disco fino a quando non sono necessarie. – janneb