当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
答案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