Usterka segmentacji (porzucenie rdzenia) – dokąd? co to jest? i dlaczego?

W przypadku błędu segmentacji w systemie Linux na terminalu zostanie wydrukowany komunikat o błędzie Segmentation fault (core dumped) (jeśli taki istnieje ), a program zostanie zakończony. Jako programista C / C ++ zdarza mi się to dość często i zwykle to ignoruję i przechodzę do gdb, odtwarzając moją poprzednią akcję, aby ponownie wywołać nieprawidłowe odwołanie do pamięci. Zamiast tego pomyślałem, że być może będę mógł użyć tego „rdzenia”, ponieważ ciągłe uruchamianie gdb jest raczej żmudne i nie zawsze mogę odtworzyć błąd segmentacji.

Mam trzy pytania:

  • Gdzie jest zrzucony ten nieuchwytny „rdzeń”?
  • Co on zawiera?
  • Co mogę zrobić z tym?

Komentarze

  • Zwykle potrzebujesz tylko polecenia gdb path-to-your-binary path-to-corefile, następnie info stack, a następnie Ctrl-d. Jedyną niepokojącą rzeczą jest to, że zrzucanie rdzeni jest dla Ciebie czymś normalnym.
  • Nie tak bardzo zwykle , bardziej sporadycznie – w większości przypadków ' z powodu literówek lub czegoś, co zmieniłem i nie ' nie wywłaszczyłem wyniku.

Odpowiedź

Jeśli inni sprzątają …

… zazwyczaj nic nie znajdujesz. Ale na szczęście Linux moduł obsługi, który możesz określić w czasie wykonywania. W /usr/src/linux/Documentation/sysctl/kernel.txt znajdziesz:

[/ proc / sys / kernel /] core_pattern służy do określenia nazwy wzorca core dumpfile.

  • Jeśli pierwszy znak wzorzec to „|”, jądro potraktuje resztę wzorca jako polecenie do uruchomienia. Zrzut pamięci zostanie zapisany na standardowe wejście tego programu zamiast do pliku.

( dzięki )

A c według źródła jest to obsługiwane przez program abrt (to jest narzędzie do automatycznego raportowania błędów, nie przerywa), ale w moim Arch Linuxie jest to obsługiwane przez systemd. Możesz napisać własną procedurę obsługi lub użyć bieżącego katalogu.

Ale co tam jest?

Teraz to, co zawiera, jest specyficzne dla systemu, ale zgodnie z wszechwiedząca encyklopedia :

[Zrzut rdzenia] składa się z zarejestrowanego stanu pamięci roboczej programu komputerowego w określonym czasie […]. W praktyce inne kluczowe elementy stanu programu są zwykle zrzucane w tym samym czasie, w tym rejestry procesora, które mogą zawierać licznik programu i wskaźnik stosu, informacje o zarządzaniu pamięcią, oraz inne flagi i informacje dotyczące procesora i systemu operacyjnego.

… więc w zasadzie zawiera wszystko gdb kiedykolwiek chciałem i nie tylko.

Tak, ale wolałbym, abym był szczęśliwy zamiast gdb

Oboje możecie być szczęśliwi, ponieważ gdb załaduje każdy zrzut rdzenia, o ile masz dokładną kopię pliku wykonywalnego: gdb path/to/binary my/core.dump. Powinieneś wtedy móc kontynuować działalność w zwykły sposób i denerwować się próbą naprawienia błędów i niepowodzeniem zamiast próby ich odtworzenia.

Odpowiedź

Ponadto, jeśli ulimit -c zwróci 0, wówczas żaden plik zrzutu pamięci nie zostanie zapisany.

Zobacz Gdzie szukać podstawowego pliku wygenerowanego przez awarię aplikacji linuxowej?

Możesz także wywołać zrzut pamięci ręcznie za pomocą CTRL \ , co kończy proces i powoduje zrzut pamięci.

Odpowiedź

Podstawowy plik zwykle nosi nazwę core i znajduje się w bieżącym katalogu roboczym procesu. Istnieje jednak długa lista powodów, dla których plik core nie zostałby wygenerowany i może on znajdować się zupełnie gdzie indziej, pod inną nazwą. Zobacz stronę podręcznika core.5 , aby uzyskać szczegółowe informacje:

OPIS

Domyślną akcją niektórych sygnałów jest spowodowanie zakończenia procesu i utworzenie pliku zrzutu pamięci , a plik dysku zawierający obraz pamięci procesu w momencie zakończenia. Ten obraz może być użyty w debugerze (np. gdb (1)) do sprawdzenia stanu programu w momencie jego zakończenia. Listę sygnałów, które powodują zrzut rdzenia procesu można znaleźć w signal (7).

Jest wiele okoliczności, w których plik zrzutu pamięci nie jest tworzony:

 * The process does not have permission to write the core file. (By default, the core file is called core or core.pid, where pid is the ID of the process that dumped core, and is created in the current working directory. See below for details on naming.) Writing the core file will fail if the directory in which it is to be created is nonwritable, or if a file with the same name exists and is not writable or is not a regular file (e.g., it is a directory or a symbolic link). * A (writable, regular) file with the same name as would be used for the core dump already exists, but there is more than one hard link to that file. * The filesystem where the core dump file would be created is full; or has run out of inodes; or is mounted read-only; or the user has reached their quota for the filesystem. * The directory in which the core dump file is to be created does not exist. * The RLIMIT_CORE (core file size) or RLIMIT_FSIZE (file size) resource limits for the process are set to zero; see getrlimit(2) and the documentation of the shell"s ulimit command (limit in csh(1)). * The binary being executed by the process does not have read permission enabled. * The process is executing a set-user-ID (set-group-ID) program that is owned by a user (group) other than the real user (group) ID of the process, or the process is executing a program that has file capabilities (see capabilities(7)). (However, see the description of the prctl(2) PR_SET_DUMPABLE operation, and the description of the /proc/sys/fs/suid_dumpable file in proc(5).) * (Since Linux 3.7) The kernel was configured without the CONFIG_COREDUMP option. 

Ponadto zrzut pamięci może wykluczyć część przestrzeni adresowej procesu, jeśli madvise ( 2) Użyto flagi MADV_DONTDUMP.

Nazewnictwo plików zrzutu pamięci

Domyślnie plik zrzutu pamięci nazywa się core, ale plik / proc / sys / kernel / core_pattern (od Linuksa 2.6 i 2.4.21) można ustawić tak, aby definiował szablon używany do nadawania nazw plikom zrzutu pamięci. Szablon może zawierać specyfikatory%, które są zastępowane następującymi wartościami podczas tworzenia pliku podstawowego:

 %% a single % character %c core file size soft resource limit of crashing process (since Linux 2.6.24) %d dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE (since Linux 3.7) %e executable filename (without path prefix) %E pathname of executable, with slashes ("/") replaced by exclamation marks ("!") (since Linux 3.0). %g (numeric) real GID of dumped process %h hostname (same as nodename returned by uname(2)) %i TID of thread that triggered core dump, as seen in the PID namespace in which the thread resides (since Linux 3.18) %I TID of thread that triggered core dump, as seen in the initial PID namespace (since Linux 3.18) %p PID of dumped process, as seen in the PID namespace in which the process resides %P PID of dumped process, as seen in the initial PID namespace (since Linux 3.12) %s number of signal causing dump %t time of dump, expressed as seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) %u (numeric) real UID of dumped process 

Odpowiedź

W Ubuntu każda awaria, która się wydarzy, jest logowana do / var / crash. Wygenerowany raport o awarii można rozpakować za pomocą apport narzędzia

apport-unpack /var/crash/_crash_file.crash „ścieżka do rozpakowania”

a następnie zrzut rdzenia w rozpakowanym raporcie można odczytać za pomocą

gdb „cat ExecutablePath „CoreDump

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *