Błąd segmentacji (zrzut rdzenia) - gdzie? co to jest? i dlaczego?

16

Gdy w systemie Linux wystąpi błąd segmentacji, komunikat o błędzie Segmentation fault (core dumped)zostanie wydrukowany na terminalu (jeśli występuje), a program zostanie zakończony. Jako twórca C / C ++ zdarza mi się to dość często i zwykle ignoruję to 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ł zamiast tego użyć tego „rdzenia”, ponieważ gdbciągłe działanie jest dość nużące i nie zawsze mogę odtworzyć błąd segmentacji.

Moje pytania są trzy:

  • Gdzie jest zrzucany ten nieuchwytny „rdzeń”?
  • Co zawiera
  • Co mogę z tym zrobić?
Joe
źródło
Zwykle potrzebujesz tylko polecenia gdb path-to-your-binary path-to-corefile, a info stacknastępnie Ctrl-d. Niepokojące jest tylko to, że dumping rdzeniowy jest czymś zwyczajnym.
ott--
Nie tyle zwykle , bardziej sporadyczne - większość czasu jest to z powodu literówek czy coś zmieniłem i nie wywłaszczyć wyniku.
Joe

Odpowiedzi:

16

Jeśli inni ludzie posprzątają ...

... zwykle nic nie znajdziesz. Ale na szczęście Linux ma moduł obsługi tego, który można 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 zrzutu pamięci.

  • Jeśli pierwszym znakiem wzorca jest „|”, jądro potraktuje resztę wzorca jako polecenie do uruchomienia. Zrzut rdzenia zostanie zapisany na standardowym wejściu tego programu zamiast do pliku.

( dzięki )

Według źródła jest to obsługiwane przez abrtprogram (to jest narzędzie do automatycznego zgłaszania błędów, nie jest przerywane), ale w moim Arch Linux jest obsługiwane przez systemd. Możesz napisać własny moduł obsługi lub skorzystać z bieżącego katalogu.

Ale co tam jest?

Teraz to, co zawiera, jest specyficzne dla systemu, ale według wszechwiedzącej encyklopedii :

[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ą obejmować licznik programu i wskaźnik stosu, informacje o zarządzaniu pamięcią oraz inne flagi i informacje o procesorze i systemie operacyjnym.

... więc w zasadzie zawiera wszystko, czego gdbkiedykolwiek chciałeś, i więcej.

Tak, ale chciałbym, żebym był szczęśliwy zamiast gdb

Można zarówno być szczęśliwy, ponieważ gdbbędzie ładować żadnego zrzutu tak długo, jak masz dokładną kopię plik wykonywalny: gdb path/to/binary my/core.dump. Powinieneś być w stanie kontynuować działalność jak zwykle i denerwować się próbą naprawienia błędów zamiast próbą ich odtworzenia.

Sebb
źródło
4

Plik podstawowy jest zwykle wywoływany corei znajduje się w bieżącym katalogu roboczym procesu. Istnieje jednak długa lista powodów, dla których nie można wygenerować pliku podstawowego i może on znajdować się gdzie indziej całkowicie pod inną nazwą. Szczegółowe informacje można znaleźć na stronie podręcznika użytkownika core.5 :

OPIS

Domyślnym działaniem niektórych sygnałów jest przyczyną proces do zakończenia i stworzyć plik zrzutu pamięci , pliku na dysku zawierającego obraz pamięci procesu w czasie wypowiedzenia. Ten obraz może być użyty w debuggerze (np. Gdb (1)) do sprawdzenia stanu programu w momencie jego zakończenia. Lista sygnałów powodujących zrzut rdzenia przez proces znajduje się w signal (7).

...

Istnieją różne okoliczności, w których plik zrzutu podstawowego 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 użyto flagi madvise (2) MADV_DONTDUMP.

Nazewnictwo plików zrzutu pamięci

Domyślnie plik zrzutu pamięci nosi nazwę core, ale plik / proc / sys / kernel / core_pattern (od Linuksa 2.6 i 2.4.21) można ustawić w celu zdefiniowania szablonu, który będzie używany do nazwania plików zrzutu pamięci. Szablon może zawierać% specyfikatorów, 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
Andrew Henle
źródło
2

W Ubuntu każda awaria zostaje zalogowana do / var / crash. Wygenerowany raport o awarii można rozpakować za pomocą narzędzia

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

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

CoreDump gdb „cat ExecutablePath”

par
źródło