未生成核心转储文件
Posted
技术标签:
【中文标题】未生成核心转储文件【英文标题】:Core dump file is not generated 【发布时间】:2011-12-05 16:30:21 【问题描述】:每次我的应用程序崩溃时,都不会生成核心转储文件。我记得几天前,它在另一台服务器上生成。我正在使用 bash 中的屏幕运行应用程序,如下所示:
#!/bin/bash
ulimit -c unlimited
while true; do ./server; done
如您所见,我正在使用ulimit -c unlimited
,如果我想生成核心转储,这很重要,但当我遇到分段错误时它仍然不会生成它。
我怎样才能让它发挥作用?
【问题讨论】:
看起来不是这样,但如果你使用sudo
(可能还有其他类型的子shell)要小心:在ulimit -c unlimited ; sudo ./server-crashing
中,新的限制在@987654325时不会生效@崩溃。
【参考方案1】:
This link 包含一个很好的清单,为什么不生成核心转储:
内核会大于当前限制。 您没有转储核心(目录和文件)的必要权限。请注意,核心转储放置在转储进程的当前目录中,该目录可能与父进程不同。 验证文件系统是否可写并且有足够的可用空间。 如果工作目录中存在名为 core 的子目录,则不会转储任何核心。 如果一个名为 core 的文件已经存在但有多个硬链接,内核将不会转储 core。 验证可执行文件的权限,如果可执行文件启用了 suid 或 sgid 位,核心转储将默认禁用。如果您对文件有执行权限但没有读取权限,情况也是如此。 验证进程未更改工作目录、核心大小限制或可转储标志。 某些内核版本无法转储具有共享地址空间的进程(AKA 线程)。较新的内核版本可以转储此类进程,但会将 pid 附加到文件名中。 可执行文件可能是不支持核心转储的非标准格式。每个可执行格式都必须实现核心转储例程。 分段错误实际上可能是内核糟糕,请检查系统日志中是否有任何糟糕消息。 应用程序调用了exit()
,而不是使用核心转储处理程序。
【讨论】:
另外:如果应用程序为SIGSEGV
设置信号处理程序,则不会创建核心转储(参见***.com/questions/16697361)。
补充一点:当程序调用setuid()
例如要删除 root 权限,它不再是 core-dumpable(可执行文件不必是 suid)。使用默认 Arch Linux 配置在 Linux 3.12 上测试。我不知道为什么会发生这种情况,它没有记录在任何地方。在setuid
之后调用prctl(PR_SET_DUMPABLE, 1, ...)
可以解决此问题,因此这不是文件系统权限问题。
实际上,这记录在 prctl 手册页的 PR_SET_DUMPABLE 部分下:man7.org/linux/man-pages/man2/prctl.2.html
core(5) manpage 是(希望)关于为什么不创建核心转储的权威列表。
我要补充一点,limits.conf
仅受 PAM 认可。因此,如果您有由 systemd(或其他一些 init)启动的守护进程,limits.conf
将不会受到尊重。系统配置选项可以在:/etc/systemd/system.conf【参考方案2】:
确保您的当前目录(在崩溃时 -- server
可能会更改目录)是可写的。如果服务器调用setuid
,则该目录必须是该用户可写的。
同时检查/proc/sys/kernel/core_pattern
。这可能会将核心转储重定向到另一个目录,并且 那个 目录必须是可写的。更多信息here。
【讨论】:
是的,core_pattern 很棘手。当 Arch Linux 切换到 systemd 时,我遇到了这个问题。现在我使用echo "core" > /proc/sys/kernel/core_pattern
来按预期获取我的核心转储(默认情况下它被写入systemd-journal)。你可以花很多时间来弄清楚...
@PhilippClaßen:我需要。我也是这样做的。我想弄清楚如何以另一种方式做到这一点太难了。我试过了,但我做不到。
附带说明,该信息在 man 5 core
手册页中。该模式支持%p
和其他此类标志。
除了确保这些目录是可写的之外,请确保您正在该位置查找核心文件【参考方案3】:
检查:
$ sysctl kernel.core_pattern
查看您的转储是如何创建的(%e 将是进程名称,%t 将是系统时间)。
对于 Ubuntu,转储由 apport
在 /var/crash
中创建,但格式不同(请参阅内部文件)。
您可以通过以下方式对其进行测试:
sleep 10 &
killall -SIGSEGV sleep
如果核心转储成功,您将在分段错误指示后看到“(核心转储)”。
阅读更多:
How to generate core dump file in Ubuntu https://wiki.ubuntu.com/Apport【讨论】:
【参考方案4】:对于systemd
系统1,安装包systemd-coredump
。可以通过以下方式找到核心转储:
ls /var/lib/systemd/coredump
此外,这些核心转储以lz4
格式压缩。要解压,你可以像这样使用包liblz4-tool
:lz4 -d FILE
。为了能够使用gdb
调试解压后的核心转储,我还必须将过长的文件名重命名为更短的文件名...
1 Debian 9 Stretch
【讨论】:
您可以使用命令coredumpctl list
查看是否生成了核心转储。
这就是我在这里的原因...为什么标准机制在 Debian 9 上不起作用?我花了几个小时试图弄清楚为什么我没有转储,最后还找到了systemd-coredump
解决方案。
这里也一样。解决了我遇到的同样问题,但在 Ubuntu 18.04 中。
该死,我无法使用 apport 或 ulimit 创建核心文件。只有 systemd-coredump 有效。非常感谢【参考方案5】:
请记住,如果您从服务启动服务器,它将启动不同的 bash 会话,因此 ulimit 将不会在那里生效。尝试将其放入您的脚本本身:
ulimit -c unlimited
【讨论】:
【参考方案6】:此外,请检查以确保/var/core
或写入核心转储的任何位置有足够的磁盘空间。如果分区几乎已满或磁盘使用率为 100%,那么这就是问题所在。我的核心转储平均有几个 gig,所以您应该确保分区上至少有 5-10 gig 可用。
【讨论】:
【参考方案7】:注意:如果您自己编写了任何崩溃处理程序,则可能不会生成核心。所以搜索一下代码就行了:
signal(SIGSEGV, <handler> );
因此 SIGSEGV 将由处理程序处理,您将不会获得核心转储。
【讨论】:
【参考方案8】:这里给出的答案很好地涵盖了大多数未创建核心转储的场景。但是,在我的例子中,这些都不适用。我将此答案发布为其他答案的补充。
如果您的核心文件由于某种原因没有被创建,我建议您查看 /var/log/messages。那里可能会提示为什么不创建核心文件。就我而言,有一行说明了根本原因:
Executable '/path/to/executable' doesn't belong to any package
要解决此问题,请编辑 /etc/abrt/abrt-action-save-package-data.conf 并将 ProcessUnpackaged 从“否”更改为“是”。
ProcessUnpackaged = yes
此设置指定是否为未使用包管理器安装的二进制文件创建核心。
【讨论】:
【参考方案9】:如果您调用daemon() 然后守护进程,默认情况下当前工作目录将更改为/
。所以如果你的程序是一个守护进程,那么你应该在/
目录而不是二进制目录中寻找核心。
【讨论】:
【参考方案10】:如果您使用的是 Linux 发行版(例如 CentOS、Debian),那么查找核心文件和相关条件的最方便的方法可能是在手册页中。只需从终端运行以下命令:
man 5 core
【讨论】:
【参考方案11】:虽然这对于提出问题的人来说不会成为问题,因为他们运行的程序是使用 ulimit 命令在脚本中生成核心文件,但我想记录下 ulimit命令特定于您在其中运行它的 shell(如环境变量)。我花了太多时间在一个 shell 中运行 ulimit 和 sysctl 以及我想在另一个 shell 中转储核心的命令,并想知道为什么没有生成核心文件。
我会将它添加到我的 bashrc 中。 sysctl 在发布后适用于所有进程,但 ulimit 仅适用于发布它的 shell(可能也适用于后代)——但不适用于其他正在运行的 shell。
【讨论】:
【参考方案12】:以防万一其他人偶然发现这一点。我正在运行其他人的代码 - 确保他们没有处理信号,以便他们可以优雅地退出。我注释掉了处理,得到了核心转储。
【讨论】:
【参考方案13】:在centos中,如果你不是root账号生成core文件: 您必须设置该帐户具有root权限或登录root帐户:
vim /etc/security/limits.conf
帐号软核无限帐号硬核无限
那么,如果您使用securecrt 或其他方式登录shell:
注销,然后重新登录
【讨论】:
【参考方案14】:允许从守护进程转储 允许所有守护进程由 systemd 启动到核心转储。
编辑:/etc/systemd/system.conf 添加以下内容
DefaultLimitCORE=无穷大 编辑:/etc/sysctl.d/core.conf 添加以下内容
kernel.core_pattern = /var/lib/coredumps/core-%e-sig%s-user%u-group%g-pid%p-time%t kernel.core_uses_pid = 1 fs.suid_dumpable = 2
更多详情:https://pve.proxmox.com/wiki/Enable_Core_Dump_systemd
【讨论】:
以上是关于未生成核心转储文件的主要内容,如果未能解决你的问题,请参考以下文章