每次,我的应用程序崩溃都不会生成核心转储文件 . 我记得几天前,在另一台服务器上它生成了 was . 我正在使用bash中的屏幕运行应用程序,如下所示:
#!/bin/bash ulimit -c unlimited while true; do ./server; done
如你所见,我正在使用 ulimit -c unlimited ,如果我想生成核心转储,这很重要,但是当我遇到分段错误时它仍然不会生成它 . 我怎样才能使它工作?
ulimit -c unlimited
在centos中,如果您不是root帐户来生成核心文件:您必须设置帐户具有root权限或登录root帐户:
vim /etc/security/limits.conf帐户软核无限帐户硬核无限制
那么如果您使用securecrt或其他登录shell:
logout 然后 relogin
如果有一个Linux发行版(例如CentOS,Debian),那么查找核心文件和相关条件的最便捷方式可能在手册页中 . 只需从终端运行以下命令:
man 5 core
虽然对于提出问题的人来说这不会成为问题,因为他们运行的程序是用ulimit命令在脚本中生成核心文件,我想记录ulimit命令是特定的到你运行它的shell(如环境变量) . 我花了太多时间在一个shell中运行ulimit和sysctl,以及我想在另一个shell中转储core的命令,并想知道为什么没有生成核心文件 .
我将把它添加到我的bashrc中 . sysctl一旦发出就适用于所有进程,但是ulimit仅适用于发布它的shell(也可能是后代) - 但不适用于碰巧正在运行的其他shell .
注意:如果您自己编写了任何崩溃处理程序,则可能无法生成核心 . 因此,在线上搜索代码:
signal(SIGSEGV, <handler> );
所以SIGSEGV将由处理程序处理,你不会得到核心转储 .
以防其他人偶然发现这件事 . 我正在运行别人的代码 - 确保他们没有处理信号,所以他们可以优雅地退出 . 我评论了处理,并获得了核心转储 .
确保您当前的目录(在崩溃时 - server 可能更改目录)是可写的 . 如果服务器调用 setuid ,则该用户必须可以写入该目录 .
server
setuid
另请查看 /proc/sys/kernel/core_pattern . 这可能会将核心转储重定向到另一个目录,并且该目录必须是可写的 . 更多信息here .
/proc/sys/kernel/core_pattern
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() 而不是使用核心转储处理程序 .
exit()
校验:
$ sysctl kernel.core_pattern
查看转储是如何创建的(%e将是进程名称,%t将是系统时间) .
如果您使用的是Ubuntu,则转储是由 apport 在 /var/crash 中创建的,但格式不同(编辑文件以查看它) .
apport
/var/crash
您可以通过以下方式测试:
sleep 10 & killall -SIGSEGV sleep
如果核心转储成功,您将在分段故障指示后看到“(core dumped)” .
阅读更多:
How to generate core dump file in Ubuntu
Ubuntu
请阅读更多:
https://wiki.ubuntu.com/Apport
请记住,如果你正在启动 server from a service ,它将启动一个不同的bash会话,因此ulimit在那里不会有效 . 试着把它放在 your script itself :
为了记录,在Debian 9 Stretch( systemd )上,我不得不安装包 systemd-coredump . 然后,在文件夹 /var/lib/systemd/coredump 中生成核心转储 .
systemd
systemd-coredump
/var/lib/systemd/coredump
此外,这些coredumps以 lz4 格式压缩 . 要解压缩,您可以使用包 liblz4-tool ,如下所示: lz4 -d FILE .
lz4
liblz4-tool
lz4 -d FILE
为了能够使用 gdb 调试解压缩的coredump,我还必须将完全长的文件名重命名为更短的文件...
gdb
另外,请检查以确保 /var/core 上有足够的磁盘空间或写入核心转储的位置 . 如果分区是almos full或100%磁盘使用率那么那就是问题所在 . 我的核心转储平均几个演出,所以你应该确保在分区上至少有5-10个演出 .
/var/core
这里给出的答案很好地涵盖了未创建核心转储的大多数情况 . 但是,在我的例子中,这些都没有应用 . 我发布这个答案作为其他答案的补充 .
如果由于某种原因没有创建您的核心文件,我建议您查看/ 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
此设置指定是否为未使用包管理器安装的二进制文件创建核心 .
如果您调用daemon()然后守护进程,则默认情况下当前工作目录将更改为 / . 因此,如果您的程序是守护程序,那么您应该在 / 目录中查找核心而不是在目录中二进制文件 .
/
13 回答
在centos中,如果您不是root帐户来生成核心文件:您必须设置帐户具有root权限或登录root帐户:
那么如果您使用securecrt或其他登录shell:
logout 然后 relogin
如果有一个Linux发行版(例如CentOS,Debian),那么查找核心文件和相关条件的最便捷方式可能在手册页中 . 只需从终端运行以下命令:
虽然对于提出问题的人来说这不会成为问题,因为他们运行的程序是用ulimit命令在脚本中生成核心文件,我想记录ulimit命令是特定的到你运行它的shell(如环境变量) . 我花了太多时间在一个shell中运行ulimit和sysctl,以及我想在另一个shell中转储core的命令,并想知道为什么没有生成核心文件 .
我将把它添加到我的bashrc中 . sysctl一旦发出就适用于所有进程,但是ulimit仅适用于发布它的shell(也可能是后代) - 但不适用于碰巧正在运行的其他shell .
注意:如果您自己编写了任何崩溃处理程序,则可能无法生成核心 . 因此,在线上搜索代码:
所以SIGSEGV将由处理程序处理,你不会得到核心转储 .
以防其他人偶然发现这件事 . 我正在运行别人的代码 - 确保他们没有处理信号,所以他们可以优雅地退出 . 我评论了处理,并获得了核心转储 .
确保您当前的目录(在崩溃时 -
server
可能更改目录)是可写的 . 如果服务器调用setuid
,则该用户必须可以写入该目录 .另请查看
/proc/sys/kernel/core_pattern
. 这可能会将核心转储重定向到另一个目录,并且该目录必须是可写的 . 更多信息here .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()
而不是使用核心转储处理程序 .校验:
查看转储是如何创建的(%e将是进程名称,%t将是系统时间) .
如果您使用的是Ubuntu,则转储是由
apport
在/var/crash
中创建的,但格式不同(编辑文件以查看它) .您可以通过以下方式测试:
如果核心转储成功,您将在分段故障指示后看到“(core dumped)” .
阅读更多:
How to generate core dump file in Ubuntu
Ubuntu
请阅读更多:
https://wiki.ubuntu.com/Apport
请记住,如果你正在启动 server from a service ,它将启动一个不同的bash会话,因此ulimit在那里不会有效 . 试着把它放在 your script itself :
为了记录,在Debian 9 Stretch(
systemd
)上,我不得不安装包systemd-coredump
. 然后,在文件夹/var/lib/systemd/coredump
中生成核心转储 .此外,这些coredumps以
lz4
格式压缩 . 要解压缩,您可以使用包liblz4-tool
,如下所示:lz4 -d FILE
.为了能够使用
gdb
调试解压缩的coredump,我还必须将完全长的文件名重命名为更短的文件...另外,请检查以确保
/var/core
上有足够的磁盘空间或写入核心转储的位置 . 如果分区是almos full或100%磁盘使用率那么那就是问题所在 . 我的核心转储平均几个演出,所以你应该确保在分区上至少有5-10个演出 .这里给出的答案很好地涵盖了未创建核心转储的大多数情况 . 但是,在我的例子中,这些都没有应用 . 我发布这个答案作为其他答案的补充 .
如果由于某种原因没有创建您的核心文件,我建议您查看/ var / log / messages . 可能会有一个提示,说明为什么不创建核心文件 . 在我的例子中,有一条线说明了根本原因:
要解决此问题,请编辑/etc/abrt/abrt-action-save-package-data.conf并将ProcessUnpackaged从“no”更改为“yes” .
此设置指定是否为未使用包管理器安装的二进制文件创建核心 .
如果您调用daemon()然后守护进程,则默认情况下当前工作目录将更改为
/
. 因此,如果您的程序是守护程序,那么您应该在/
目录中查找核心而不是在目录中二进制文件 .