Cosa contiene il messaggio di backtrace GDB “0x000000000000000000 ?? ()" significare?
Domanda
Che cosa significa quando fornisce una backtrace con il seguente output?
#0 0x00000008009c991c in pthread_testcancel () from /lib/libpthread.so.2
#1 0x00000008009b8120 in sigaction () from /lib/libpthread.so.2
#2 0x00000008009c211a in pthread_mutexattr_init () from /lib/libpthread.so.2
#3 0x0000000000000000 in ?? ()
Il programma si è arrestato in modo anomalo con un segnale standard 11, errore di segmentazione. La mia applicazione è un programma FastCGI C ++ multi-thread in esecuzione su FreeBSD 6.3, usando pthread come libreria di threading.
È stato compilato con -g e tutte le tabelle dei simboli per la mia fonte sono caricate, secondo le fonti di informazione.
Come è chiaro, nessuno del mio codice attuale appare nella traccia ma invece l'errore sembra provenire da librerie pthread standard. In particolare, cos'è ?? () ????
MODIFICA : alla fine ho rintracciato il crash fino a un accesso alla memoria standard non valido nel mio codice principale. Non spiega perché la traccia dello stack sia stata danneggiata, ma questa è una domanda per un altro giorno :)
Soluzione
gdb non è stato in grado di estrarre l'indirizzo di ritorno corretto da pthread_mutexattr_init; ha ottenuto un indirizzo di 0. Il "quot" ?? " è il risultato della ricerca dell'indirizzo 0 nella tabella dei simboli. Non riesce a trovare un nome simbolico, quindi stampa un predefinito " ?? "
Purtroppo subito non so perché non sia riuscito a estrarre l'indirizzo di ritorno corretto.
Altri suggerimenti
Qualcosa che hai causato ha causato l'arresto anomalo della libreria di threading. Poiché la libreria di threading stessa non è compilata con simboli di debug (-g), non può visualizzare il file del codice sorgente o il numero di riga in cui si è verificato l'arresto anomalo. Inoltre, poiché si tratta di thread, lo stack di chiamate non punta al file. Sfortunatamente questo sarà un bug difficile da rintracciare, dovrai esaminare il tuo codice e provare a restringere quando si verifica esattamente l'incidente.
Assicurati di compilare con i simboli di debug. (Per gcc penso che sia l'opzione -g). Quindi dovresti essere in grado di ottenere informazioni più interessanti da GDB. Non dimenticare di disattivarlo quando compili la versione di produzione.
Potrei mancare qualcosa, ma questo non è indicativo di qualcuno che utilizza NULL
come puntatore a funzione?
#include <stdio.h>
typedef int (*funcptr)(void);
int
func_caller(funcptr f)
{
return (*f)();
}
int
main()
{
return func_caller(NULL);
}
Questo produce lo stesso stile di una backtrace se lo esegui in gdb:
rivendell$ gcc -g -O0 foo.c -o foo
rivendell$ gdb --quiet foo
Reading symbols for shared libraries .. done
(gdb) r
Starting program: ...
Reading symbols for shared libraries . done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x00001f9d in func_caller (f=0) at foo.c:8
#2 0x00001fb1 in main () at foo.c:14
Questo è un incidente piuttosto strano sebbene ... pthread_mutexattr_init
raramente fa altro che allocare una struttura di dati e memset
. Vorrei cercare qualcos'altro. Esiste la possibilità di librerie di threading non corrispondenti o qualcosa del genere. La mia conoscenza di BSD è un po 'datata, ma c'erano alcuni problemi al riguardo.
Forse il bug che ha causato l'incidente ha rotto la pila (parti sovrascritte della pila)? In tal caso, il backtrace potrebbe essere inutile; non ho idea di cosa fare in quel caso ...