2010-04-05 8 views

risposta

8

È perché non è stato compilato con il debug attivato. Prova gcc -g file.c

+0

Intendi dire che gdb non può essere utilizzato per eseguire il debug di programmi arbitrali? – user198729

+2

@ user198729: Puoi usare GDB per eseguire il debug di un programma arbitrario, ma devi lavorare molto più duramente se il programma non ha una tabella dei simboli. Fondamentalmente, la tabella dei simboli indica al debugger le funzioni e le variabili, i numeri di riga e i file sorgente e, se manca, tutto ciò che rimane è assemblatore. –

+0

@ Jonathan Leffler, sembra che tu intenda che è ancora possibile eseguire il debug del programma anche se non ha una tabella dei simboli, puoi fare un esempio? – user198729

2

La tabella dei simboli contiene informazioni di debug che indicano a un debugger quali posizioni di memoria corrispondono a quali simboli (come nomi di funzioni e nomi di variabili) nel file di codice sorgente originale. La tabella dei simboli è solitamente memorizzata all'interno dell'eseguibile, sì.

gdb ti sta dicendo che non riesce a trovare quella tabella. Se hai compilato con gcc, a meno che non hai usato il flag -g, non includerà la tabella dei simboli nel file. Il metodo più semplice è probabilmente quello di ricompilare il tuo file con -g. gdb dovrebbe quindi trovare automaticamente le informazioni sulla tabella dei simboli.

Aggiungere il flag -g agli argomenti della riga di comando di gcc o al Makefile utilizzato per compilare il programma. (Un sacco di volte, ci sarà una variabile chiamata CFLAGS o simile all'interno del Makefile).

Se si sta tentando di eseguire il debug di un programma arbitrario di terze parti, molte volte le informazioni saranno state "eliminate" da esso. Questo viene fatto per rendere più difficile la reverse engineering e per ridurre le dimensioni del file eseguibile. A meno che tu non abbia accesso al codice sorgente e possa compilare tu stesso il programma, ti sarà molto difficile usare gdb su di esso.

+0

Perché alcuni altri strumenti come softice possono eseguire il debug di un programma arbitrario, non stanno usando le stesse tecniche di gdb? – user198729

+0

Circa le stesse tecniche, sì. Puoi fare cose simili con gdb come mettere breakpoint su chiamate di sistema o esaminare il codice assembly o guardare i valori di registro o il contenuto di specifici indirizzi di memoria, anche senza una tabella di simboli. Potresti anche voler controllare strace o ltrace se sei su Linux. – RarrRarrRarr

+0

Ma indipendentemente dal comando che digito, gdb risponde sempre con 'Nessuna tabella dei simboli caricata. Usa il comando "file"., Sembra impossibile per il debug di un programma senza tabella dei simboli ... O forse c'è qualcosa che mi manca? – user198729

18

Esistono due gruppi di simboli utilizzati da gdb.

Il set -g è un simbolo di debug, che semplifica le cose in quanto consente di visualizzare il codice e analizzare le variabili durante il debug.

Un'altra serie di simboli è inclusa per impostazione predefinita durante la compilazione. Questi sono i simboli di collegamento e vivono nella tabella dei simboli ELF (eseguibile in formato collegabile). Questo contiene molte meno informazioni rispetto ai simboli di debug, ma contiene le cose più importanti, come gli indirizzi delle cose nel tuo eseguibile (o libreria o file oggetto). Senza queste informazioni gdb non saprà nemmeno dove si trova il main, quindi (gdb) break main fallirebbe.

Se non si dispone dei simboli di debug (-g), si sarà comunque in grado di (gdb) break main ma gdb non avrà alcun concetto delle righe di codice nel file sorgente. Quando provi a scorrere il codice, avanzerai solo 1 istruzione macchina alla volta, anziché una linea alla volta.

Il comando striscia viene spesso utilizzato per strip simboli off da un eseguibile (o un altro file oggetto). Questo è spesso usato se non vuoi che qualcuno sia in grado di vedere i simboli o se vuoi risparmiare spazio nel file. Le tabelle dei simboli possono diventare grandi. Strip rimuove sia i simboli di debug che i simboli del linker, ma ha diversi switch a riga di comando che possono limitare ciò che rimuove.

Se si esegue il comando file sul programma, una delle cose che ti dirà è tempo o meno l'eseguibile è stato rimosso.

$ gcc my_prog.c -o my_prog 
$ file my_prog 
my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped 
$ strip my_prog 
my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped 
$ 
+0

sei sicuro che i simboli linker ('.dynsym', giusto?) Vengono rimossi da' strip'? Secondo [questo] (http://stackoverflow.com/a/8624223/264047) non lo sono. –

+2

'strip' ha opzioni che controllano quali simboli sono e non vengono rimossi. Il comportamento predefinito di solito non rompe le cose. – nategoose

+0

@nategoose puoi dirci se i simboli di debug sono o meno inclusi tra i simboli nella tabella dei simboli ELF. In altre parole, GDB usa solo i simboli di debugging quando l'applicazione è stata compilata con -g? –

1

Trovare il punto di accesso dell'applicazione.

objdump -f main 

    main:  file format elf32-i386 
    architecture: i386, flags 0x00000112: 
    EXEC_P, HAS_SYMS, D_PAGED 
    start address 0x08048054 

Mettere un punto di interruzione non utilizzando il debugger GNU

gdb 

    exec-file main 
    break *0x8048054 
    set disassemble-next-line on 
    run 

Poi passo attraverso il codice

gdb 

    stepi 

Note speciali

Se si utilizza l'ultima versione di Ubuntu non ne risentirebbe, ma potresti incontrare questo bug se stai usando Ubuntu 10.04 o più vecchio

https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/151518G 

La soluzione sarebbe avviare il debugging all'indirizzo del punto di ingresso più uno.

Problemi correlati