核心转储文件不会生成
每次,我的应用程序崩溃核心转储文件不会生成。 我记得几天前,在另一台服务器上生成的。 我正在使用bash运行应用程序,如下所示:
#!/bin/bash ulimit -c unlimited while true; do ./server; done
正如你所看到的,我正在使用ulimit -c unlimited
,这是非常重要的,如果我想生成一个核心转储,但它仍然不会生成它,当我有一个分段错误。 我怎样才能使它工作?
确保你的当前目录(在崩溃的时候 – server
可能改变目录)是可写的。 如果服务器调用setuid
,则该目录必须由该用户写入。
还要检查/proc/sys/kernel/core_pattern
。 这可能会将核心转储redirect到另一个目录,并且该目录必须是可写的。 更多信息在这里 。
这个链接包含一个很好的核对清单,为什么不生成核心转储:
- 核心将会大于目前的限制。
- 您没有转储核心(目录和文件)所需的权限。 请注意,核心转储放置在转储过程的当前目录中,该目录可能与父进程不同。
- validation文件系统是否可写,并有足够的可用空间。
- 如果在工作目录中存在名为core的子目录,则不会转储核心。
- 如果名为core的文件已经存在,但有多个硬链接,内核将不会转储核心。
- validation可执行文件的权限,如果可执行文件启用了suid或sgid位,默认情况下将禁用核心转储。 如果您具有执行权限但文件没有读取权限,则情况也是如此。
- validation该进程是否未更改工作目录,核心大小限制或可丢弃标志。
- 某些内核版本不能转储具有共享地址空间(AKA线程)的进程。 较新的内核版本可以转储这些进程,但会将pid附加到文件名。
- 可执行文件可能是不支持核心转储的非标准格式。 每个可执行格式必须实现一个核心转储例程。
- 分段错误实际上可能是内核Oops,请检查系统日志是否有任何Oops消息。
- 该应用程序调用
exit()
而不是使用核心转储处理程序。
检查:
$ sysctl kernel.core_pattern
看看你的转储是如何创build的(%e将是进程名称,%t将是系统时间)。
如果你有Ubuntu,你的转储是通过/var/crash
的apport
创build的,但是格式不同(编辑文件来查看它)。
你可以testing它:
sleep 10 & killall -SIGSEGV sleep
如果核心转储成功,则会在分段故障指示后看到“(核心转储)”。
阅读更多:
如何在Ubuntu中生成核心转储文件
Ubuntu的
请阅读更多:
记住,如果你是从一个服务启动服务器 ,它将启动一个不同的bash会话,所以ulimit在那里不会有效。 尝试把它放在你的脚本本身 :
ulimit -c unlimited
另外,请检查以确保在/var/core
上有足够的磁盘空间,或者在核心转储写入的地方。 如果分区是almos full或100%的磁盘使用率那么这将是问题。 我的核心转储平均有几个演出,所以你应该确保分区上至less有5-10个演出。
这里给出的答案涵盖了大多数没有创build核心转储的场景。 但是,在我的例子中,这些都没有应用。 我发布这个答案作为其他答案的补充。
如果你的核心文件不是因为什么原因而被创build的,我推荐查看/ var / log / messages。 那里可能有一个提示为什么没有创build核心文件。 在我的情况下,有一条线说明根本原因:
Executable '/path/to/executable' doesn't belong to any package
要解决此问题,请编辑/etc/abrt/abrt-action-save-package-data.conf,并将ProcessUnpackaged从“no”更改为“yes”。
ProcessUnpackaged = yes
此设置指定是否为未与软件包pipe理器一起安装的二进制文件创build核心。
如果一个人在Linux发行版上(例如CentOS,Debian),那么可能是find核心文件和相关条件的最方便的方法是在手册页中。 只需从terminal运行以下命令:
man 5 core
为了logging,在Debian 9 Stretch( systemd
)上,我必须安装软件包systemd-coredump
。 之后,在文件夹/var/lib/systemd/coredump
中生成核心转储文件。
而且,这些lz4
以lz4
格式被压缩。 要解压缩,可以使用如下所示的软件包liblz4-tool
: lz4 -d FILE
。
为了能够使用gdb
debugging解压缩的核心转储,我还必须重命名为最短的文件名更短
虽然对于提问的人来说这不会是一个问题,因为他们运行的是用ulimit命令在脚本中生成核心文件的程序,我想logging下ulimit命令是特定的到你运行它的shell(比如环境variables)。 我花了太多时间在一个shell中运行ulimit和sysctl和东西,以及我想在另一个shell中转储核心的命令,并想知道为什么不生成核心文件。
我将把它添加到我的bashrc中。 sysctl一旦发布就可以用于所有进程,但ulimit只适用于发布它的shell(也可能是后代) – 但是对于其他正在运行的shell不适用。
注意:如果您自己编写了任何崩溃处理程序,那么核心可能不会生成。 因此,寻找与线上的东西的代码:
signal(SIGSEGV, <handler> );
所以SIGSEGV将被处理程序处理,您将不会得到核心转储。
如果调用守护进程() ,然后守护进程,默认情况下当前工作目录将变为/
。 所以如果你的程序是一个守护进程,那么你应该在/
目录中寻找一个核心,而不是在二进制文件的目录中。