Jeśli chcesz poznać przyczynę, możesz zarejestrować sig nal obsługi, coś jak:
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);
}
A potem gdzieś trzeba zarejestrować go:
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");
}
Zasadniczo zarejestrować sygnał, że pożary po SIGSEGV została wydana, i masz jakieś dodatkowe informacje, cytując strona 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
Są mapa do dwóch podstawowych powodów f lub otrzymanie błędu seg - albo strona, do której wchodziłeś, nie była w ogóle mapowana, albo nie mogłeś wykonać żadnej operacji, którą próbujesz wykonać na tej stronie.
Po uruchomieniu obsługi sygnału wylogowuje się i zastępuje domyślną akcję. Powoduje to, że operacja, która nie została wykonana ponownie, może zostać przechwycona przez normalną trasę. Jest to normalne zachowanie strony błędu (prekursora do uzyskania błędu seg), aby działały strony takie jak popieranie popytu.
Można użyć funkcji ['backtrace'] (http://linux.die.net/man/3/backtrace). Ale naprawdę polecam uruchomienie programu w debugerze, pozwoli ci nie tylko zobaczyć ślad, ale podejść do stosu wywołań i zbadać zmienne. –
"przeczytaj o plikach zrzutu pamięci" - zdecydowanie polecam. Zrzucają wszystko w pamięci i można je otworzyć za pomocą 'gdb' i właściwego pliku wykonywalnego. To da ci szansę zobaczenia, co dokładnie się stało (chyba że pamięć nie jest pomieszana, ale to dość rzadki przypadek) - zobacz wartości dowolnych zmiennych, ślad wstecz, wątki itp. (Oczywiście, byłoby miło mieć max debugowanie poziom i brak optymalizacji dla tego typu badania) –
hmm .. typ '* ptr' to' char', ale '" hello "to typ' char * '. powinieneś prawdopodobnie przypisać znak ('* ptr = 'h';') lub użyć 'memmove()' lub podobnego, aby przykład był poprawny.jak to jest, pobiera adres stałej ciągowej, rzuca ją na liczbę całkowitą, goli ją do 1 bajtu, a następnie segfaults przypisując ją do '* ptr' – SingleNegationElimination