什么是强制应用核心转储和退出的正确方法?

What is the correct way to force an app to core dump and quit?

本文关键字:退出 方法 转储 应用 核心 什么      更新时间:2023-10-16

我刚刚遇到一些使用kill系统调用向应用程序发送SIGSEGV信号的代码。这背后的基本原理是,这将迫使应用程序进行核心转储并退出。我觉得这太不对了,这是正常的做法吗?

如果希望生成核心转储,

SIGQUIT是发送给程序的正确信号。kill是发送信号的正确命令行程序(当然它的名字不好,因为不是所有的信号都会杀死程序)。

注意,您不应该向程序发送随机信号,不是所有的信号都会产生核心转储。它们中的许多将由程序本身处理,要么被消耗,要么被忽略,要么引发其他处理。因此发送SIGSEGV是错误的。


GCC说:http://www.gnu.org/s/libc/manual/html_node/Termination-Signals.html

POSIX/Unix说:http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html

是。kill有点命名不当——它可以发送任何信号。kill有许多用途,根本不会导致过程被杀死!

如果您想让一个应用程序从另一个程序中转储它的核心,那么几乎唯一的方法就是通过信号。SEGV会很好。或者,你可以将调试器连接到程序并冻结它,查看它的寄存器等,而不杀死它。

如果你想从应用程序中转储一个核心,有更好的方法,比如通过assert()。

所以,不,向程序发送SEGV并不是特别错误。你也可以发送类似SIGILL的东西来表示非法指令,或者除以零的信号。

在Unix/Linux中这样做的方法是调用abort(),它将向当前进程发送SIGABORT。另一个选项是raise(),你可以指定你想要发送什么信号到当前进程。

Richard Stevens (_Advanced Programming in UNIX Environment)写道:

内核的生成是大多数Unix的一个实现特性。它不属于POSIX.1。

他列出了12个信号,其默认动作是终止一个核心(ANSI: SIGABRT, SIGFPE, SIGILL, SIGSEGV, POSIX: SIGQUIT, Other: SIGBUS, SIGEMT, SIGIOT, SIGSYS, SIGTRAP, SIGXCPU, SIGXFSZ),所有这些信号都是可重写的(不可重写的两个信号是SIGKILL和SIGSTOP)。

我从来没有见过不使用默认信号处理程序来生成核心的方法。

因此,如果您的目标是生成一个核心和停止,最好是选择一个信号,其默认处理程序完成这项工作(SIGSEGV完成这项工作),如果您正在使用它,则重置信号的默认处理程序,然后使用kill。