首页 文章

未生成核心转储文件

提问于
浏览
50

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

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

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

13 回答

  • 0

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

    vim /etc/security/limits.conf帐户软核无限帐户硬核无限制

    那么如果您使用securecrt或其他登录shell:

    logout 然后 relogin

  • 3

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

    man 5 core
    
  • 0

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

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

  • 53

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

    signal(SIGSEGV, <handler> );
    

    所以SIGSEGV将由处理程序处理,你不会得到核心转储 .

  • 1

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

  • 5

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

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

  • 1

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

    • 核心将大于当前限制 .

    • 您不要't have the necessary permissions to dump core (directory and file). Notice that core dumps are placed in the dumping process'当前目录可能与父进程不同 .

    • 验证文件系统是否可写并且有足够的可用空间 .

    • 如果工作目录中存在名为core的子目录,则不会转储核心 .

    • 如果名为core的文件已经存在但有多个硬链接,则内核不会转储核心 .

    • 验证可执行文件的权限,如果可执行文件启用了suid或sgid位,则默认情况下将禁用核心转储 . 如果您具有执行权限但对文件没有读取权限,情况也是如此 .

    • 验证进程未更改工作目录,核心大小限制或可转储标志 .

    • 某些内核版本无法转储具有共享地址空间(AKA线程)的进程 . 较新的内核版本可以转储此类进程,但会将pid附加到文件名 .

    • 可执行文件可能采用非标准格式,不支持核心转储 . 每种可执行格式都必须实现核心转储例程 .

    • 分段错误实际上可能是内核Oops,检查系统日志中是否有任何Oops消息 .

    • 应用程序调用 exit() 而不是使用核心转储处理程序 .

  • 4

    校验:

    $ 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

  • 0

    请记住,如果你正在启动 server from a service ,它将启动一个不同的bash会话,因此ulimit在那里不会有效 . 试着把它放在 your script itself

    ulimit -c unlimited
    
  • 1

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

    此外,这些coredumps以 lz4 格式压缩 . 要解压缩,您可以使用包 liblz4-tool ,如下所示: lz4 -d FILE .

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

  • 0

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

  • 46

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

    如果由于某种原因没有创建您的核心文件,我建议您查看/ var / log / messages . 可能会有一个提示,说明为什么不创建核心文件 . 在我的例子中,有一条线说明了根本原因:

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

    要解决此问题,请编辑/etc/abrt/abrt-action-save-package-data.conf并将ProcessUnpackaged从“no”更改为“yes” .

    ProcessUnpackaged = yes
    

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

  • 1

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

相关问题