2013-05-22 20 views
7

Gdy moja aplikacja ulega awarii z błędem segmentacji, chciałbym uzyskać zrzut pamięci z systemu. To zrobić poprzez skonfigurowanie przed rękąLinux: obsługa błędu segmentacji i generowanie zrzutu pamięci

ulimit -c unlimited 

Chciałbym również mieć wskazanie w moich dziennikach aplikacji, że usterka została segmentacja wystąpił. Robię to za pomocą sigaction(). Jeśli jednak to zrobię, sygnał nie osiągnie domyślnej obsługi, a zrzut pamięci nie zostanie zapisany.

W jaki sposób mogę zrzucić zarówno rdzeń systemu, jak i linię dziennika z mojej własnej procedury obsługi sygnału w tym samym czasie?

Odpowiedz

1

Odpowiedź: ustaw sygnał z flagą SA_RESETHAND i po prostu wróć z programu obsługi. Ta sama instrukcja występuje ponownie, powodując ponownie błąd segmentacji i wywołanie domyślnej procedury obsługi.

+0

Czy możesz opracować? – Short

+0

Obawiam się, że nie mogę. – shoosh

+1

Nie działa to w wersji Redhat 6, której testowałem i powoduje pętlę regresywną, w której program obsługi nie jest resetowany. Działa, jeśli przechowujesz stary moduł obsługi podczas wywoływania sigaction i jawnie resetujesz go w procedurze obsługi SIGSEGV. – phenompbg

5
  1. Zastąp domyślną procedurę obsługi sygnału dla SIGSEGV, aby wywołać niestandardową funkcję rejestrowania.
  2. Po zarejestrowaniu, przywróć i uruchom domyślną procedurę obsługi, która utworzy zrzut główny.

Oto przykładowy program używając signal:

void sighandler(int signum) 
{ 
    myLoggingFunction(); 

    // this is the trick: it will trigger the core dump 
    signal(signum, SIG_DFL); 
    kill(getpid(), signum); 
} 

int main() 
{ 
    signal(SIGSEGV, sighandler); 

    // ... 
} 

Ta sama idea powinna również współpracować z sigaction.

Źródło: How to handle SIGSEGV, but also generate a core dump

+0

Co dla mnie działa, to ustawienie sygnału do sygnalizowania (signum, SIG_DFL); i pozwól, aby program obsługi sygnału powrócił. – Vincent

Powiązane problemy