Se si desidera conoscere la causa è possibile registrare un sig handler nale, qualcosa di simile:
void handler(int signum, siginfo_t *info, void *context)
{
struct sigaction action = {
.sa_handler = SIG_DFL,
.sa_sigaction = NULL,
.sa_mask = 0,
.sa_flags = 0,
.sa_restorer = NULL
};
fprintf(stderr, "Fault address: %p\n", info->si_addr);
switch (info->si_code) {
case SEGV_MAPERR:
fprintf(stderr, "Address not mapped.\n");
break;
case SEGV_ACCERR:
fprintf(stderr, "Access to this address is not allowed.\n");
break;
default:
fprintf(stderr, "Unknown reason.\n");
break;
}
/* unregister and let the default action occur */
sigaction(SIGSEGV, &action, NULL);
}
E poi da qualche parte è necessario registrarlo:
struct sigaction action = {
.sa_handler = NULL,
.sa_sigaction = handler,
.sa_mask = 0,
.sa_flags = SA_SIGINFO,
.sa_restorer = NULL
};
if (sigaction(SIGSEGV, &action, NULL) < 0) {
perror("sigaction");
}
In pratica si registra un segnale che viene generato quando SIGSEGV è consegnato, e si ottiene un po 'di informazioni aggiuntive, per citare la pagina man:
The following values can be placed in si_code for a SIGSEGV signal:
SEGV_MAPERR address not mapped to object
SEGV_ACCERR invalid permissions for mapped object
Questi mappa per due motivi fondamentali f o ottenendo un errore di seg, o la pagina a cui si è eseguito l'accesso non è stata mappata affatto o non è stato consentito eseguire alcuna operazione che si è tentato di eseguire su quella pagina.
Qui, dopo che il gestore del segnale si è attivato, si annulla automaticamente e sostituisce l'azione predefinita. Ciò causa l'operazione che non è stata eseguita nuovamente in modo che possa essere catturata dal percorso normale. Questo è il comportamento normale di un errore di pagina (il precursore per ottenere un errore di seg) in modo che funzioni come il paging della domanda funzionino.
È possibile utilizzare la funzione ['backtrace'] (http://linux.die.net/man/3/backtrace). Ma in realtà ti raccomando di eseguire il tuo programma in un debugger, ti permetterà non solo di vedere il backtrace, ma di salire sullo stack delle chiamate ed esaminare le variabili. –
"leggi i file di dump di base": li raccomando vivamente. Scaricano tutto nella memoria e puoi quindi aprirli con 'gdb' e l'eseguibile corretto. Questo ti darà la possibilità di vedere cosa è successo esattamente (a meno che la memoria non sia incasinata, ma è un caso piuttosto raro) - vedi i valori di qualsiasi variabile, backtrace, thread, ecc (ovviamente, sarebbe bello avere un debug massimo livello e nessuna ottimizzazione per questo tipo di indagine) –
hmm .. il tipo di '* ptr' è' char', ma '" ciao "il tipo di' s è 'char *'. probabilmente dovresti assegnare un carattere ('* ptr = 'h';') o usare un 'memmove()' o simile per essere corretto nell'esempio.così com'è, prende l'indirizzo della costante di stringa, lo converte in numero intero, lo riduce a 1 byte e quindi segfaults assegnandolo a '* ptr' – SingleNegationElimination