我有一个进程在Linux得到一个分割错误。当它失败时,我如何告诉它生成一个核心转储?


当前回答

如上所述,这里提出的真正问题是如何在未启用核心转储的系统上启用它们。这个问题在这里得到了解答。

如果您希望了解如何为挂起进程生成核心转储,那么答案是

gcore <pid>

如果gcore在您的系统上不可用,那么

kill -ABRT <pid>

不要使用kill -SEGV,因为它经常会调用信号处理程序,使诊断卡住进程更加困难

其他回答

这通常是足够的:

ulimit -c unlimited

注意,这不会在ssh部分之间持续存在!要添加持久性:

echo '* soft core unlimited' >> /etc/security/limits.conf

现在,如果你正在使用Ubuntu,“apport”可能正在运行。下面是检查方法:

sudo systemctl status apport.service

如果是,你可能会在以下位置之一找到核心转储:

/var/lib/apport/coredump 
/var/crash

如果您想更改核心转储的位置

确保您拥有创建文件的权限,并且该目录存在于您发送核心转储的目录中!

举个例子。注意,这将不会持续重启:

sysctl -w kernel.core_pattern=/coredumps/core-%e-%s-%u-%g-%p-%t
mkdir /coredumps

确保正在崩溃的进程有权写入该文件。最简单的方法是这样的例子:

chmod 777 /coredumps

测试内核转储是否工作

> crash.c
gcc -Wl,--defsym=main=0 crash.c
./a.out
==output== Segmentation fault (core dumped)

如果上面没有显示“核心转储”,说明有些东西不正常。

值得一提的是,如果你建立了一个系统,那么事情就会有点不同。通常情况下,通过core_pattern sysctl值将核心文件通过systemd-coredump(8)进行管道传输。核心文件大小rlimit通常已经配置为“unlimited”。

然后可以使用coredumpctl(1)检索核心转储。

coredump等的存储由coredump.conf(5)配置。在coredumpctl手册页中有一些如何获取核心文件的示例,但简而言之,它看起来像这样:

找到核心文件:

[vps@phoenix]~$ coredumpctl list test_me | tail -1
Sun 2019-01-20 11:17:33 CET   16163  1224  1224  11 present /home/vps/test_me

获取核心文件:

[vps@phoenix]~$ coredumpctl -o test_me.core dump 16163

这取决于您使用的shell。如果使用bash,则ulimit命令控制与程序执行相关的几个设置,例如是否应该转储core。如果你输入

ulimit -c unlimited

然后这将告诉bash,它的程序可以转储任何大小的内核。如果你愿意,你可以指定一个大小,比如52M,而不是无限,但在实践中,这不应该是必要的,因为核心文件的大小可能永远不会成为你的问题。

在tcsh中,您需要输入

limit coredumpsize unlimited

默认情况下,您将得到一个核心文件。检查进程的当前目录是否可写,否则不会创建核心文件。

最好使用系统调用setrlimit以编程方式打开核心转储。

例子:

#include <sys/resource.h>

bool enable_core_dump(){    
    struct rlimit corelim;

    corelim.rlim_cur = RLIM_INFINITY;
    corelim.rlim_max = RLIM_INFINITY;

    return (0 == setrlimit(RLIMIT_CORE, &corelim));
}