未生成核心转储文件
每次我的应用程序崩溃时,都不会生成核心转储文件。我记得几天前,在另一台服务器上生成了它。我在 bash 中使用 screen 运行应用程序,如下所示:
#!/bin/bash
ulimit -c unlimited
while true; do ./server; done
如您所见,我正在使用 ulimit -c unlimited
如果我想生成核心转储,这很重要,但它仍然没有当我遇到分段错误时生成它。 我怎样才能让它发挥作用?
Every time, my application crash a core dump file is not generated. I remember that few days ago, on another server it was generated. I'm running the app using screen in bash like this:
#!/bin/bash
ulimit -c unlimited
while true; do ./server; done
As you can see I'm using ulimit -c unlimited
which is important if I want to generate a core dump, but it still doesn't generate it, when I got an segmentation fault.
How can I make it work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
此链接包含一个很好的清单,说明为什么未生成核心转储:
exit()
而不是使用核心转储处理程序。This link contains a good checklist why core dumps are not generated:
exit()
instead of using the core dump handler.确保您当前的目录(在崩溃时——
服务器
可能会更改目录)是可写的。如果服务器调用setuid
,则该目录必须可由该用户写入。另请检查
/proc/sys/kernel/core_pattern
。这可能会将核心转储重定向到另一个目录,并且该目录必须是可写的。更多信息此处。Make sure your current directory (at the time of crash --
server
may change directories) is writable. If the server callssetuid
, the directory has to be writable by that user.Also check
/proc/sys/kernel/core_pattern
. That may redirect core dumps to another directory, and that directory must be writable. More info here.对于
systemd
系统1,安装软件包systemd-coredump
。可以通过以下方式找到核心转储:此外,这些核心转储以
lz4
格式压缩。要解压,您可以使用包liblz4-tool
,如下所示:lz4 -d FILE
。为了能够使用gdb
调试解压后的 coredump,我还必须将非常长的文件名重命名为较短的文件名...1 Debian 9 Stretch
For
systemd
systems1, install the packagesystemd-coredump
. Coredumps can be found via:Furthermore, these coredumps are compressed in the
lz4
format. To decompress, you can use the packageliblz4-tool
like this:lz4 -d FILE
. To be able to debug the decompressed coredump usinggdb
, I also had to rename the utterly long filename into something shorter...1 Debian 9 Stretch
检查:
查看转储是如何创建的(%e 将是进程名称,%t 将是系统时间)。
对于 Ubuntu,转储是由
apport
在/var/crash
中创建的,但格式不同(请参阅内部文件)。您可以通过以下方式进行测试:
如果核心转储成功,您将在分段错误指示后看到“(core dumped)”。
了解更多:
Check:
to see how your dumps are created (%e will be the process name, and %t will be the system time).
For Ubuntu, dumps are created by
apport
in/var/crash
, but in different format (see inside file).You can test it by:
If core dumping is successful, you will see “(core dumped)” after the segmentation fault indication.
Read more:
请记住,如果您从服务启动服务器,它将启动不同的 bash 会话,因此 ulimit 在那里不起作用。尝试将其放入您的脚本本身中:
Remember if you are starting the server from a service, it will start a different bash session so the ulimit won't be effective there. Try to put this in your script itself:
如果使用的是 Linux 发行版(例如 CentOS、Debian),那么查找核心文件和相关条件的最容易的方法可能是在手册页中。只需从终端运行以下命令:
If one is on a Linux distro (e.g. CentOS, Debian) then perhaps the most accessible way to find out about core files and related conditions is in the man page. Just run the following command from a terminal:
另外,请检查以确保
/var/core
或写入核心转储的任何位置有足够的磁盘空间。如果分区几乎已满或磁盘使用率为 100%,那么这就是问题所在。我的核心转储平均为几 GB,因此您应该确保分区上至少有 5-10 GB 可用。Also, check to make sure you have enough disk space on
/var/core
or wherever your core dumps get written. If the partition is almos full or at 100% disk usage then that would be the problem. My core dumps average a few gigs so you should be sure to have at least 5-10 gig available on the partition.注意:如果您自己编写了任何崩溃处理程序,则可能不会生成核心。因此,搜索带有某些内容的代码:
这样 SIGSEGV 将由处理程序处理,并且您将不会获得核心转储。
Note: If you have written any crash handler yourself, then the core might not get generated. So search for code with something on the line:
so the SIGSEGV will be handled by handler and you will not get the core dump.
这里给出的答案很好地涵盖了大多数未创建核心转储的场景。然而,就我而言,这些都不适用。我将这个答案作为其他答案的补充发布。
如果由于某种原因没有创建您的核心文件,我建议查看 /var/log/messages。其中可能暗示为什么未创建核心文件。就我而言,有一行说明了根本原因:
要解决此问题,请编辑 /etc/abrt/abrt-action-save-package-data.conf 并将 ProcessUnpackaged 从“no”更改为“yes”。
此设置指定是否为未随包管理器安装的二进制文件创建核心。
The answers given here cover pretty well most scenarios for which core dump is not created. However, in my instance, none of these applied. I'm posting this answer as an addition to the other answers.
If your core file is not being created for whatever reason, I recommend looking at the /var/log/messages. There might be a hint in there to why the core file is not created. In my case there was a line stating the root cause:
To work around this issue edit /etc/abrt/abrt-action-save-package-data.conf and change ProcessUnpackaged from 'no' to 'yes'.
This setting specifies whether to create core for binaries not installed with package manager.
如果您调用 daemon() 然后守护进程,通过默认当前工作目录将更改为
/
。因此,如果您的程序是守护程序,那么您应该在/
目录中查找核心,而不是在二进制文件的目录中。If you call daemon() and then daemonize a process, by default the current working directory will change to
/
. So if your program is a daemon then you should be looking for a core in/
directory and not in the directory of the binary.虽然这对于提出问题的人来说不会成为问题,因为他们运行的程序是使用 ulimit 命令在脚本中生成核心文件,但我想记录一下 ulimit 命令是特定的到运行它的 shell(如环境变量)。我花了太多时间在一个 shell 中运行 ulimit 和 sysctl 等东西,以及在另一个 shell 中运行我想要转储核心的命令,并想知道为什么没有生成核心文件。
我会将其添加到我的 bashrc 中。 sysctl 一旦发出就适用于所有进程,但 ulimit 仅适用于发出它的 shell(也可能是后代) - 但不适用于碰巧正在运行的其他 shell。
Although this isn't going to be a problem for the person who asked the question, because they ran the program that was to produce the core file in a script with the ulimit command, I'd like to document that the ulimit command is specific to the shell in which you run it (like environment variables). I spent way too much time running ulimit and sysctl and stuff in one shell, and the command that I wanted to dump core in the other shell, and wondering why the core file was not produced.
I will be adding it to my bashrc. The sysctl works for all processes once it is issued, but the ulimit only works for the shell in which it is issued (maybe also the descendents too) - but not for other shells that happen to be running.
以防万一其他人偶然发现这一点。我正在运行其他人的代码 - 确保他们没有处理信号,以便他们可以正常退出。我注释掉了处理,并得到了核心转储。
Just in case someone else stumbles on this. I was running someone else's code - make sure they are not handling the signal, so they can gracefully exit. I commented out the handling, and got the core dump.
在centos中,如果你不是root账户来生成core文件:
您必须设置该帐户具有root权限或登录root帐户:
然后如果您登录使用 securecrt 或其他 shell:
注销,然后重新登录
In centos,if you are not root account to generate core file:
you must be set the account has a root privilege or login root account:
then if you in login shell with securecrt or other:
logout and then relogin
允许从守护进程转储
允许所有守护进程由 systemd 启动以进行核心转储。
编辑: /etc/systemd/system.conf 添加以下
DefaultLimitCORE=infinity
编辑: /etc/sysctl.d/core.conf 添加以下
kernel.core_pattern = /var/lib/coredumps/core-%e-sig%s-user%u-group%g-pid%p-time%t
内核.core_uses_pid = 1
fs.suid_dumpable = 2
更多详细信息:https://pve.proxmox.com/wiki/Enable_Core_Dump_systemd
Allow Dump from Daemons
To allow all daemons witch are started by systemd to core dump.
Edit: /etc/systemd/system.conf add following
DefaultLimitCORE=infinity
Edit: /etc/sysctl.d/core.conf add following
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
more detail: https://pve.proxmox.com/wiki/Enable_Core_Dump_systemd
当 capability 设置为它。
删除它可以重新生成核心转储。
另请参阅:如何从 setcap 获取核心转储可执行文件?
Our application stopped producing core dumps when a capability was set to it.
Removing it allowed the re-generation of coredumps.
See also: How do I get a coredump from a setcap executable?