未生成核心转储文件

时间:2011-10-11 21:52:57

标签: linux gdb coredump

每次我的应用程序崩溃都不会生成核心转储文件。我记得几天前,在另一台服务器上生成了 。我正在使用bash中的屏幕运行应用程序,如下所示:

#!/bin/bash
ulimit -c unlimited
while true; do ./server; done

正如您所看到的,我正在使用ulimit -c unlimited,如果我想生成核心转储,这很重要,但是当我遇到分段错误时,它仍然不会生成核心转储。 我怎样才能使它发挥作用?

14 个答案:

答案 0 :(得分:53)

This link包含一个很好的清单,为什么不生成核心转储:

  • 核心将大于当前限制。
  • 您没有转储核心(目录和文件)所需的权限。请注意,核心转储放在转储进程的当前目录中,该目录可能与父进程不同。
  • 验证文件系统是否可写并且有足够的可用空间。
  • 如果工作目录中存在名为core的子目录,则不会转储核心。
  • 如果名为core的文件已经存在但有多个硬链接,则内核不会转储核心。
  • 验证可执行文件的权限,如果可执行文件启用了suid或sgid位,则默认情况下将禁用核心转储。如果您具有执行权限但对文件没有读取权限,情况也是如此。
  • 验证进程未更改工作目录,核心大小限制或可转储标志。
  • 某些内核版本无法转储具有共享地址空间(AKA线程)的进程。较新的内核版本可以转储此类进程,但会将pid附加到文件名。
  • 可执行文件可能采用非标准格式,不支持核心转储。每种可执行格式都必须实现核心转储例程。
  • 分段错误实际上可能是内核Oops,请检查系统日志中是否有任何Oops消息。
  • 应用程序调用{​​{1}}而不是使用核心转储处理程序。

答案 1 :(得分:49)

确保您当前的目录(在崩溃时 - server可能更改目录)是可写的。如果服务器调用setuid,该目录必须是该用户可写的。

同时检查/proc/sys/kernel/core_pattern。这可能会将核心转储重定向到另一个目录,并且 目录必须是可写的。更多信息here

答案 2 :(得分:5)

检查:

$ sysctl kernel.core_pattern

查看您的转储是如何创建的(%e将是进程名称,%t将是系统时间)。

如果你是Ubuntu,你的转储是由apport中的/var/crash创建的,但格式不同(编辑文件以查看它)。

您可以通过以下方式进行测试:

sleep 10 &
killall -SIGSEGV sleep

如果核心转储成功,您将在分段故障指示后看到“(core dumped)”。

了解更多:

How to generate core dump file in Ubuntu


<强> Ubuntu的

请阅读更多信息:

https://wiki.ubuntu.com/Apport

答案 3 :(得分:4)

请记住,如果您从服务启动服务器,它将启动一个不同的bash会话,因此ulimit在那里不会有效。尝试将其放入您的脚本本身

ulimit -c unlimited

答案 4 :(得分:3)

为了记录,在Debian 9 Stretch(systemd)上,我必须安装包systemd-coredump。之后,核心转储在/var/lib/systemd/coredump文件夹中生成。

此外,这些coredumps以lz4格式压缩。要解压缩,您可以使用liblz4-tool这样的包:lz4 -d FILE

为了能够使用gdb调试解压缩的coredump,我还必须将完全长的文件名重命名为更短的文件...

答案 5 :(得分:1)

另外,请检查以确保/var/core或核心转储写入的位置有足够的磁盘空间。如果分区是almos full或100%磁盘使用率那么那就是问题所在。我的核心转储平均几个演出,所以你应该确保在分区上至少有5-10个演出。

答案 6 :(得分:1)

这里给出的答案很好地涵盖了未创建核心转储的大多数情况。但是,在我的例子中,这些都没有应用。我将此答案作为其他答案的补充发布。

如果由于某种原因未创建核心文件,我建议查看/ var / log / messages。可能会有一个提示,说明为什么不创建核心文件。就我而言,有一条线说明了根本原因:

Executable '/path/to/executable' doesn't belong to any package

要解决此问题,请编辑/etc/abrt/abrt-action-save-package-data.conf并从&#39; no&#39;更改ProcessUnpackaged。到是的&#39;。

ProcessUnpackaged = yes

此设置指定是否为未使用包管理器安装的二进制文件创建核心。

答案 7 :(得分:1)

如果您调用daemon()然后守护进程,则默认情况下当前工作目录将更改为/。因此,如果您的程序是守护程序,那么您应该在/目录中查找核心,而不是在二进制文件的目录中。

答案 8 :(得分:1)

如果有一个Linux发行版(例如CentOS,Debian),那么查找核心文件和相关条件的最便捷方式可能在手册页中。只需从终端运行以下命令:

DropDownList

答案 9 :(得分:0)

虽然对于提出这个问题的人来说这不会成为一个问题,因为他们运行的程序是用ulimit命令在脚本中生成核心文件,我想记录ulimit命令特定于运行它的shell(如环境变量)。我花了太多时间在一个shell中运行ulimit和sysctl和stuff,以及我想在另一个shell中转储core的命令,并想知道为什么没有生成核心文件。

我将把它添加到我的bashrc中。 sysctl一旦发出就适用于所有进程,但是ulimit仅适用于发布它的shell(也可能是后代) - 但不适用于碰巧正在运行的其他shell。

答案 10 :(得分:0)

注意:如果您自己编写了任何崩溃处理程序,则可能无法生成核心。因此,在线上搜索代码:

signal(SIGSEGV, <handler> );

因此SIGSEGV将由处理程序处理,您将无法获得核心转储。

答案 11 :(得分:0)

以防其他人偶然发现这件事。我正在运行别人的代码 - 确保他们没有处理信号,所以他们可以优雅地退出。我评论了处理,并得到了核心转储。

答案 12 :(得分:0)

在centos中,如果您不是root帐户来生成核心文件: 您必须设置该帐户具有root特权或登录root帐户:

  

vim /etc/security/limits.conf   

     

帐户 软核无限制
帐户 硬核无限制

然后,如果您使用securecrt或其他登录shell:

注销,然后重新登录

答案 13 :(得分:0)

允许从守护进程转储 允许所有由 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