Zależy to od używanej powłoki. Jeśli używasz bash, to polecenie ulimit kontroluje kilka ustawień związanych z wykonywaniem programu, takich jak to, czy powinieneś zrzucić rdzeń. Jeśli wpiszesz
ulimit -c unlimited
to powie bashowi, że jego programy mogą zrzucać rdzenie dowolnego rozmiaru. Jeśli chcesz, możesz określić rozmiar taki jak 52M zamiast nieograniczonego, ale w praktyce nie powinno to być konieczne, ponieważ rozmiar podstawowych plików prawdopodobnie nigdy nie będzie dla ciebie problemem.
@lzprgmr: Aby wyjaśnić: powodem, dla którego zrzuty rdzenia nie są generowane domyślnie, jest to, że limit nie jest ustawiony i / lub ustawiony na 0, co zapobiega zrzutowi rdzenia. Ustawiając limit nieograniczony, gwarantujemy, że zrzuty rdzenia mogą być zawsze generowane.
Eli Courtwright,
6
Ten link jest głębszy i daje kilka dodatkowych opcji umożliwiających generowanie zrzutów rdzenia w systemie Linux. Jedyną wadą jest to, że niektóre polecenia / ustawienia pozostają niewyjaśnione.
Salsa
6
W wersji bash 4.1.2 (1) nie można określić limitów zwolnienia, takich jak 52M, co powoduje wyświetlenie komunikatu o błędnym numerze. Strona podręcznika mówi, że „Wartości są w przyrostach 1024-bajtowych”.
a1an
4
Cóż, miałem „mały” projekt OpenGL, który kiedyś zrobił coś dziwnego i spowodował awarię serwera X. Kiedy się ponownie zalogowałem, zobaczyłem ładny mały plik podstawowy 17 GB (na partycji 25 GB). Zdecydowanie dobrym pomysłem jest ograniczenie rozmiaru pliku rdzenia :)
IceCool,
1
@PolarisUser: Jeśli chcesz mieć pewność, że twoja partycja nie zostanie zjedzona, zalecam ustawienie limitu około 1 gig. Powinno to być wystarczająco duże, aby poradzić sobie z każdym rozsądnym zrzutem rdzenia, a jednocześnie nie grozić wykorzystaniem całej pozostałej przestrzeni na dysku twardym.
Eli Courtwright
60
Jak wyjaśniono powyżej, prawdziwym pytaniem jest tutaj, jak włączyć zrzuty pamięci w systemie, w którym nie są włączone. Odpowiedź na to pytanie znajduje się tutaj.
Jeśli przyszedłeś tutaj z nadzieją, aby dowiedzieć się, jak wygenerować zrzut podstawowy dla zawieszonego procesu, odpowiedź brzmi:
gcore <pid>
jeśli gcore nie jest dostępny w twoim systemie, to
kill -ABRT <pid>
Nie używaj kill -SEGV, ponieważ często wywołuje to procedurę obsługi sygnału, co utrudnia zdiagnozowanie zablokowanego procesu
Myślę, że jest o wiele bardziej prawdopodobne, że -ABRTwywoła procedurę obsługi sygnału niż -SEGV, ponieważ przerwanie jest bardziej prawdopodobne do odzyskania niż segfault. (Jeśli poradzisz sobie z segfault, normalnie uruchomi się on ponownie, jak tylko wyjdzie twój program obsługi.) Lepszym wyborem sygnału do wygenerowania zrzutu rdzenia jest -QUIT.
celticminstrel
32
Aby sprawdzić, gdzie generowane są zrzuty pamięci, uruchom:
sysctl kernel.core_pattern
lub:
cat /proc/sys/kernel/core_pattern
gdzie %ejest nazwa procesu i %tczas systemowy. Możesz to zmienić /etc/sysctl.confi ponownie załadować sysctl -p.
Jeśli rdzeń pliki nie są generowane (test go: sleep 10 &a killall -SIGSEGV sleep) sprawdzić granice, których autorem jest: ulimit -a.
Jeśli rozmiar twojego podstawowego pliku jest ograniczony, uruchom:
ulimit -c unlimited
aby było nieograniczone.
Następnie przetestuj ponownie, jeśli zrzut rdzenia zakończy się powodzeniem, po wskazaniu błędu segmentacji zobaczysz komunikat „(zrzut rdzenia)”:
W przypadku Ubuntu, aby szybko przywrócić normalne zachowanie (zrzut pliku podstawowego w bieżącym katalogu), po prostu zatrzymaj usługę apport za pomocą „sudo service apport stop”. Należy również pamiętać, że jeśli działasz w oknie dokowanym, to ustawienie jest kontrolowane w systemie hosta, a nie w kontenerze.
Digicrat,
26
Na końcu podłączyłem gdb do procesu, zanim się zawiesił, a potem, kiedy dostał błąd, wykonałem generate-core-filepolecenie. To wymuszone generowanie zrzutu rdzenia.
Aby odpowiedzieć na Ritwik G, aby dołączyć proces do gdb, po prostu uruchom gdb i wpisz „attach <pid>”, gdzie <pid> to numer pid procesu, który chcesz dołączyć.
Jean-Dominique Frattini,
(w skrócie jako ge)
user202729
Jeśli mają nowe pytanie, powinni zadać nowe pytanie zamiast zadawać komentarz.
user202729
Najdziwniejsze jest już ustawiony ulimit -cdo unlimited, ale plik rdzeń jest tworzony nie uspokaja The generate-core-fileplików w sesji gdb ma utworzyć plik core, dzięki.
CodyChan
19
Być może mógłbyś to zrobić w ten sposób, ten program pokazuje, jak złapać błąd segmentacji i wysyła do debuggera (jest to oryginalny kod użyty poniżej AIX) i drukuje ślad stosu aż do błędu segmentacji. Będziesz musiał zmienić sprintfzmienną, aby użyć jej gdbw przypadku Linuksa.
#include <stdio.h>#include <signal.h>#include <stdlib.h>#include <stdarg.h>
static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *,...);
struct sigaction sigact;
char *progname;
int main(int argc, char **argv){
char *s;
progname =*(argv);
atexit(cleanup);
init_signals();
printf("About to seg fault by assigning zero to *s\n");*s =0;
sigemptyset(&sigact.sa_mask);return0;}
void init_signals(void){
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags =0;
sigaction(SIGINT,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGSEGV);
sigaction(SIGSEGV,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGBUS);
sigaction(SIGBUS,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGQUIT);
sigaction(SIGQUIT,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGHUP);
sigaction(SIGHUP,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGKILL);
sigaction(SIGKILL,&sigact,(struct sigaction *)NULL);}
static void signal_handler(int sig){if(sig == SIGHUP) panic("FATAL: Program hanged up\n");if(sig == SIGSEGV || sig == SIGBUS){
dumpstack();
panic("FATAL: %s Fault. Logged StackTrace\n",(sig == SIGSEGV)?"Segmentation":((sig == SIGBUS)?"Bus":"Unknown"));}if(sig == SIGQUIT) panic("QUIT signal ended program\n");if(sig == SIGKILL) panic("KILL signal ended program\n");if(sig == SIGINT);}
void panic(const char *fmt,...){
char buf[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
exit(-1);}
static void dumpstack(void){/*Got this routine from http://www.whitefang.com/unix/faq_toc.html
**Section6.5.Modified to redirect to file to prevent clutter
*//*This needs to be changed...*/
char dbx[160];
sprintf(dbx,"echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);/*Change the dbx to gdb */
system(dbx);return;}
void cleanup(void){
sigemptyset(&sigact.sa_mask);/*Do any cleaning up chores here */}
Być może trzeba będzie dodatkowo dodać parametr, aby uzyskać gdb zrzucić rdzeń jak pokazano tutaj w tym blogu tutaj .
aby sprawdzić, czy kill -s SEGV <PID>plik rdzenia zostanie zapisany, możesz zabić odpowiedni proces za pomocą cmd (nie powinno to być potrzebne, na wypadek gdyby nie zapisano żadnego pliku rdzenia, można to wykorzystać jako sprawdzenie):
# kill -s SEGV <PID>
Po zapisaniu pliku podstawowego upewnij się, że ponownie dezaktywujesz ustawienia zrzutu rdzeniowego w powiązanych plikach (1./2./3.)!
W kroku 3, jak „ponownie uruchomić” terminal? Masz na myśli restart?
Naveen
@Naveen nie, wystarczy zamknąć terminal i otworzyć nowy, wydaje się, że można po prostu ulimit -c unlimitedpodłączyć terminal do tymczasowego rozwiązania, ponieważ tylko edycja ~/.bashrcwymaga ponownego uruchomienia terminala, aby zmiany odniosły skutek.
mrgloom
4
Domyślnie otrzymasz plik podstawowy. Sprawdź, czy bieżący katalog procesu jest zapisywalny, czy nie zostanie utworzony żaden plik podstawowy.
Przez „bieżący katalog procesu” masz na myśli $ cwd w momencie uruchomienia procesu? ~ / abc> / usr / bin / cat def w przypadku awarii kota, czy bieżący katalog to pytanie ~ / abc lub / usr / bin?
Nathan Fellman
5
~ / abc. Hmm, komentarze muszą mieć 15 znaków!
Mark Harrison
5
Byłby to katalog bieżący w czasie SEGV. Ponadto procesy działające z innym efektywnym użytkownikiem i / lub grupą niż rzeczywisty użytkownik / grupa nie będą zapisywać plików podstawowych.
Darron
2
Lepiej włączyć zrzut pamięci programowo za pomocą wywołania systemowego setrlimit.
plik podstawowy wygenerowany po awarii, nie trzeba ulimit -c unlimitedtego robić w środowisku wiersza poleceń, a następnie ponownie uruchomić aplikację.
kgbook
Nie chcę zrzutu rdzenia za każdym razem, gdy ulega awarii, tylko wtedy, gdy użytkownik skontaktuje się ze mną jako programistą, aby go zobaczyć. Jeśli ulegnie awarii 100 razy, nie potrzebuję 100 zrzutów rdzenia, aby na to spojrzeć.
Nathan Fellman
W takim przypadku lepiej użyć ulimit -c unlimited. Możesz także skompilować z definicją marco, aplikacja nie będzie zawierała enable_core_dumpsymbolu, jeśli nie zdefiniuje tego makra w momencie wydania, a otrzymasz zrzut pamięci podstawowej zastąpiony wersją debugowania.
kgbook
nawet jeśli jest zakwalifikowany przez makro, to wciąż wymaga ode mnie ponownej kompilacji, jeśli chcę wygenerować zrzut pamięci, zamiast po prostu wykonać polecenie w powłoce przed ponownym uruchomieniem.
Nathan Fellman
1
Warto wspomnieć, że jeśli masz skonfigurowane ustawienia systemowe , rzeczy wyglądają nieco inaczej. W konfiguracji zwykle przesyłane są pliki podstawowe za pomocą core_patternwartości sysctl systemd-coredump(8). Rozmiar pliku rlimit rdzenia zwykle byłby już skonfigurowany jako „nieograniczony”.
Następnie można odzyskać zrzuty pamięci za pomocą coredumpctl(1).
Przechowywanie zrzutów pamięci itp. Jest konfigurowane przez coredump.conf(5). Istnieją przykłady, jak uzyskać podstawowe pliki na stronie podręcznika coredumpctl, ale w skrócie wyglądałoby to tak:
Znajdź plik podstawowy:
[vps@phoenix]~$ coredumpctl list test_me | tail -1Sun2019-01-2011:17:33 CET 161631224122411 present /home/vps/test_me
Niektóre odpowiedzi sugerują zmianę core_pattern. Pamiętaj, że ten plik może zostać zastąpiony przez usługę apport po ponownym uruchomieniu.
Samo zatrzymanie apportu nie zadziałało
ulimit -cWartość może przebrać się automatycznie, gdy starasz inne odpowiedzi wstęgi. Pamiętaj o regularnym sprawdzaniu tego podczas konfigurowania tworzenia zrzutu pamięci.
Odpowiedzi:
Zależy to od używanej powłoki. Jeśli używasz bash, to polecenie ulimit kontroluje kilka ustawień związanych z wykonywaniem programu, takich jak to, czy powinieneś zrzucić rdzeń. Jeśli wpiszesz
to powie bashowi, że jego programy mogą zrzucać rdzenie dowolnego rozmiaru. Jeśli chcesz, możesz określić rozmiar taki jak 52M zamiast nieograniczonego, ale w praktyce nie powinno to być konieczne, ponieważ rozmiar podstawowych plików prawdopodobnie nigdy nie będzie dla ciebie problemem.
W tcsh wpisałeś
źródło
Jak wyjaśniono powyżej, prawdziwym pytaniem jest tutaj, jak włączyć zrzuty pamięci w systemie, w którym nie są włączone. Odpowiedź na to pytanie znajduje się tutaj.
Jeśli przyszedłeś tutaj z nadzieją, aby dowiedzieć się, jak wygenerować zrzut podstawowy dla zawieszonego procesu, odpowiedź brzmi:
jeśli gcore nie jest dostępny w twoim systemie, to
Nie używaj kill -SEGV, ponieważ często wywołuje to procedurę obsługi sygnału, co utrudnia zdiagnozowanie zablokowanego procesu
źródło
-ABRT
wywoła procedurę obsługi sygnału niż-SEGV
, ponieważ przerwanie jest bardziej prawdopodobne do odzyskania niż segfault. (Jeśli poradzisz sobie z segfault, normalnie uruchomi się on ponownie, jak tylko wyjdzie twój program obsługi.) Lepszym wyborem sygnału do wygenerowania zrzutu rdzenia jest-QUIT
.Aby sprawdzić, gdzie generowane są zrzuty pamięci, uruchom:
lub:
gdzie
%e
jest nazwa procesu i%t
czas systemowy. Możesz to zmienić/etc/sysctl.conf
i ponownie załadowaćsysctl -p
.Jeśli rdzeń pliki nie są generowane (test go:
sleep 10 &
akillall -SIGSEGV sleep
) sprawdzić granice, których autorem jest:ulimit -a
.Jeśli rozmiar twojego podstawowego pliku jest ograniczony, uruchom:
aby było nieograniczone.
Następnie przetestuj ponownie, jeśli zrzut rdzenia zakończy się powodzeniem, po wskazaniu błędu segmentacji zobaczysz komunikat „(zrzut rdzenia)”:
Zobacz także: zrzut rdzenia - ale pliku rdzenia nie ma w bieżącym katalogu?
Ubuntu
W Ubuntu zrzuty rdzenia są obsługiwane przez Apport i mogą być zlokalizowane w
/var/crash/
. Jest jednak domyślnie wyłączony w stabilnych wersjach.Aby uzyskać więcej informacji, sprawdź: Gdzie mogę znaleźć zrzut podstawowy w Ubuntu? .
System operacyjny Mac
W przypadku systemu macOS zobacz: Jak generować zrzuty pamięci w Mac OS X?
źródło
Na końcu podłączyłem gdb do procesu, zanim się zawiesił, a potem, kiedy dostał błąd, wykonałem
generate-core-file
polecenie. To wymuszone generowanie zrzutu rdzenia.źródło
ge
)ulimit -c
dounlimited
, ale plik rdzeń jest tworzony nie uspokaja Thegenerate-core-file
plików w sesji gdb ma utworzyć plik core, dzięki.Być może mógłbyś to zrobić w ten sposób, ten program pokazuje, jak złapać błąd segmentacji i wysyła do debuggera (jest to oryginalny kod użyty poniżej
AIX
) i drukuje ślad stosu aż do błędu segmentacji. Będziesz musiał zmienićsprintf
zmienną, aby użyć jejgdb
w przypadku Linuksa.Być może trzeba będzie dodatkowo dodać parametr, aby uzyskać gdb zrzucić rdzeń jak pokazano tutaj w tym blogu tutaj .
źródło
Jest więcej rzeczy, które mogą wpływać na generowanie zrzutu pamięci. Spotkałem te:
/proc/sys/kernel/core_pattern
./proc/sys/fs/suid_dumpable
może uniemożliwić wygenerowanie rdzenia.Jest więcej sytuacji, które mogą uniemożliwić generowanie, które są opisane na stronie man - try
man core
.źródło
Aby aktywować zrzut główny, wykonaj następujące czynności:
W
/etc/profile
komentarzu wiersz:W
/etc/security/limits.conf
Wykomentuj linii:uruchom cmd
limit coredumpsize unlimited
i sprawdź za pomocą cmdlimit
:aby sprawdzić, czy
kill -s SEGV <PID>
plik rdzenia zostanie zapisany, możesz zabić odpowiedni proces za pomocą cmd (nie powinno to być potrzebne, na wypadek gdyby nie zapisano żadnego pliku rdzenia, można to wykorzystać jako sprawdzenie):Po zapisaniu pliku podstawowego upewnij się, że ponownie dezaktywujesz ustawienia zrzutu rdzeniowego w powiązanych plikach (1./2./3.)!
źródło
Dla Ubuntu 14.04
Sprawdź zrzut zrzutu pamięci włączony:
Jedna z linii powinna być:
Jeśli nie :
gedit ~/.bashrc
i dodajulimit -c unlimited
na końcu pliku i zapisz, uruchom ponownie terminal.Zbuduj swoją aplikację z informacjami debugowania:
W Makefile
-O0 -g
Uruchom aplikację, która tworzy zrzut pamięci (plik zrzutu pamięci o nazwie „core” powinien zostać utworzony w pobliżu pliku nazwa_aplikacji):
Uruchom pod gdb:
źródło
ulimit -c unlimited
podłączyć terminal do tymczasowego rozwiązania, ponieważ tylko edycja~/.bashrc
wymaga ponownego uruchomienia terminala, aby zmiany odniosły skutek.Domyślnie otrzymasz plik podstawowy. Sprawdź, czy bieżący katalog procesu jest zapisywalny, czy nie zostanie utworzony żaden plik podstawowy.
źródło
Lepiej włączyć zrzut pamięci programowo za pomocą wywołania systemowego
setrlimit
.przykład:
źródło
ulimit -c unlimited
tego robić w środowisku wiersza poleceń, a następnie ponownie uruchomić aplikację.ulimit -c unlimited
. Możesz także skompilować z definicją marco, aplikacja nie będzie zawierałaenable_core_dump
symbolu, jeśli nie zdefiniuje tego makra w momencie wydania, a otrzymasz zrzut pamięci podstawowej zastąpiony wersją debugowania.Warto wspomnieć, że jeśli masz skonfigurowane ustawienia systemowe , rzeczy wyglądają nieco inaczej. W konfiguracji zwykle przesyłane są pliki podstawowe za pomocą
core_pattern
wartości sysctlsystemd-coredump(8)
. Rozmiar pliku rlimit rdzenia zwykle byłby już skonfigurowany jako „nieograniczony”.Następnie można odzyskać zrzuty pamięci za pomocą
coredumpctl(1)
.Przechowywanie zrzutów pamięci itp. Jest konfigurowane przez
coredump.conf(5)
. Istnieją przykłady, jak uzyskać podstawowe pliki na stronie podręcznika coredumpctl, ale w skrócie wyglądałoby to tak:Znajdź plik podstawowy:
Pobierz plik podstawowy:
źródło
Ubuntu 19.04
Wszystkie inne odpowiedzi same mi nie pomogły. Ale poniższe podsumowanie wykonało zadanie
Utwórz
~/.config/apport/settings
z następującą zawartością:(To mówi apportowi, aby również zapisywał zrzuty pamięci dla niestandardowych aplikacji)
sprawdzić:
ulimit -c
. Jeśli wyświetla 0, napraw to za pomocąNa wszelki wypadek, gdy uruchomisz ponownie apport:
Pliki awarii są teraz zapisywane w
/var/crash/
. Ale nie można ich używać z gdb. Aby użyć ich z gdb, użyjDalsza informacja:
core_pattern
. Pamiętaj, że ten plik może zostać zastąpiony przez usługę apport po ponownym uruchomieniu.ulimit -c
Wartość może przebrać się automatycznie, gdy starasz inne odpowiedzi wstęgi. Pamiętaj o regularnym sprawdzaniu tego podczas konfigurowania tworzenia zrzutu pamięci.Bibliografia:
źródło