【问题标题】: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时不会生效@崩溃。

标签: linux gdb coredump


【解决方案1】:

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

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

【讨论】:

  • 另外:如果应用程序为SIGSEGV 设置信号处理程序,则不会创建核心转储(参见stackoverflow.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

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

阅读更多:

【讨论】:

    【解决方案4】:

    对于systemd 系统1,安装包systemd-coredump。可以通过以下方式找到核心转储:

    ls /var/lib/systemd/coredump
    

    此外,这些核心转储以lz4 格式压缩。要解压,你可以像这样使用包liblz4-toollz4 -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

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-01-24
                        • 2011-08-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多