분할 오류(코어 덤프) - 어디로 가야 할까요? 그것은 무엇입니까? 왜?

분할 오류(코어 덤프) - 어디로 가야 할까요? 그것은 무엇입니까? 왜?

Linux에서 분할 오류가 발생하면 오류 메시지가 Segmentation fault (core dumped)터미널(있는 경우)에 인쇄되고 프로그램이 종료됩니다. C/C++ 개발자로서 이런 일이 자주 발생하며 일반적으로 이를 무시하고 계속 진행하여 gdb잘못된 메모리 참조가 다시 트리거되도록 이전 작업을 다시 만듭니다. 대신 gdb에 항상 실행하는 것이 다소 지루하고 분할 오류를 항상 재현할 수는 없기 때문에 이 "코어"를 사용할 수 있을 것이라고 생각했습니다 .

내 질문은 세 가지입니다.

  • 이 찾기 어려운 "핵심"은 어디에 버려졌습니까?
  • 그것은 무엇을 포함하고 있습니까?
  • 그걸로 무엇을 할 수 있나요?

답변1

다른 사람이 청소하면..

...보통 아무것도 찾지 못합니다. 그러나 다행히도 Linux에는 런타임 시 지정할 수 있는 핸들러가 있습니다. 존재하다/usr/src/linux/Documentation/sysctl/kernel.txt당신은 발견 할 것이다:

core_pattern코어 덤프 파일 모드 이름을 지정하는 데 사용됩니다.

  • 패턴의 첫 번째 문자가 "|"이면 커널은 패턴의 나머지 부분을 실행할 명령으로 처리합니다. 코어 덤프는 파일이 아닌 프로그램의 표준 입력에 기록됩니다.

(바라보다코어가 덤프되었지만 코어 파일이 현재 디렉터리에 없습니까?StackOverflow에서)

소스에 따르면 이것은 abrt프로그래밍 방식으로 처리되지만(즉, 중단이 아닌 자동 오류 보고 도구) 내 Arch Linux에서는 systemd에 의해 처리됩니다. 자신만의 핸들러를 작성하거나 현재 디렉터리를 사용할 수 있습니다.

그런데 안에는 무엇이 있나요?

여기에 포함된 내용은 이제 시스템마다 다르지만 다음을 기반으로 합니다.모든 것을 아는 백과사전:

[코어 덤프]는 특정 시간 [...]에 컴퓨터 프로그램 작업 메모리의 기록된 상태로 구성됩니다. 실제로 프로그램 카운터와 스택 포인터, 메모리 관리 정보, 기타 프로세서와 운영 체제 플래그 및 정보를 포함할 수 있는 프로세서 레지스터를 포함하여 프로그램 상태의 다른 중요한 부분이 동시에 덤프되는 경우가 많습니다.

...그래서 여기에는 기본적으로 gdb실패를 분석하는 데 필요한 모든 것이 포함되어 있습니다(실패를 일으킨 실행 파일 제외).

응, 하지만 gdb 대신 행복했으면 좋겠어

gdb실행 파일의 정확한 복사본이 있는 한 모든 코어 덤프가 로드되므로 모두 만족할 수 있습니다 gdb path/to/binary my/core.dump. 그러면 오류를 재현하려고 시도하고 실패하는 대신 특정 오류를 분석할 수 있어야 합니다.

답변2

또한 ulimit -c반환 되면 0코어 덤프 파일이 기록되지 않습니다.

바라보다Linux 애플리케이션 충돌로 생성된 코어 파일을 어디에서 검색할 수 있나요?

CTRL-를 사용하여 수동으로 코어 덤프를 실행할 수도 있습니다. \그러면 프로세스가 종료되고 코어 덤프가 발생합니다.

답변3

코어 파일은 일반적으로 core프로세스의 현재 작업 디렉터리에 호출되고 위치합니다. 그러나 코어 파일을 생성할 수 없는 데에는 여러 가지 이유가 있으며 파일이 다른 이름으로 완전히 다른 위치에 있을 수 있습니다. 보다core.5 매뉴얼 페이지세부:

설명하다

일부 신호의 기본 동작은 프로세스를 종료하고 다음을 생성하는 것입니다.코어 덤프 파일,프로세스가 종료되었을 때 메모리 이미지가 포함된 디스크 파일입니다. 이 이미지는 디버거(예: gdb(1))와 함께 사용되어 프로그램 종료 시 프로그램 상태를 검사할 수 있습니다. 프로세스가 코어를 덤프하도록 하는 신호 목록은 signal(7)에서 찾을 수 있습니다.

...

코어 덤프 파일이 생성되지 않는 몇 가지 상황이 있습니다.

   *  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.

또한 madvise(2) MADV_DONTDUMP 플래그가 사용되는 경우 코어 덤프는 프로세스 주소 공간의 일부를 제외할 수 있습니다.

코어 덤프 파일 이름 지정

기본적으로 코어 덤프 파일의 이름은 core로 지정되지만 /proc/sys/kernel/core_pattern 파일(Linux 2.6 및 2.4.21부터)을 설정하여 코어 덤프 파일 이름 지정을 위한 템플릿을 정의할 수 있습니다. 템플릿에는 코어 파일을 생성할 때 다음 값으로 대체되는 % 지정자가 포함될 수 있습니다.

       %%  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

답변4

Ubuntu에서는 발생하는 모든 충돌이 에 기록됩니다 /var/crash. 생성된 충돌 보고서는 다음 도구를 사용하여 압축을 풀 수 있습니다 apport.

apport-unpack /var/crash/_crash_file.crash <path to unpack>

압축 해제 보고서의 코어 덤프는 다음을 사용하여 읽을 수 있습니다.

gdb "$(cat ExecutablePath)" CoreDump

관련 정보