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

C++ 强制应用核心转储并退出的正确方法是什么?,c++,c,core,signals,C++,C,Core,Signals,我刚刚遇到一些代码,它使用kill系统调用向应用程序发送SIGSEGV信号。这背后的理由是,这将迫使应用程序核心转储并退出。这对我来说似乎很不对,这是正常的做法吗?是的kill有点命名错误——它可以发送任何信号。kill有很多用法,它们根本不会导致进程被终止 如果你想让一个应用程序从另一个程序中转储它的内核,几乎唯一的方法就是通过一个信号。SEGV就可以了。或者,您可以将调试器连接到程序,冻结它,查看它的寄存器等,而不终止它 如果您想从应用程序中转储内核,有更好的方法,比如通过assert()

我刚刚遇到一些代码,它使用kill系统调用向应用程序发送SIGSEGV信号。这背后的理由是,这将迫使应用程序核心转储并退出。这对我来说似乎很不对,这是正常的做法吗?

是的
kill
有点命名错误——它可以发送任何信号。
kill
有很多用法,它们根本不会导致进程被终止

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

如果您想从应用程序中转储内核,有更好的方法,比如通过assert()


所以,不,向程序发送SEGV并不是特别错误。您也可以发送类似SIGILL的非法指令,或除零信号。一切正常。

在Unix/Linux中执行此操作的方法是调用abort(),它将SIGABORT发送到当前进程。另一个选项是raise(),您可以在其中指定要发送到当前进程的信号。

SIGQUIT是要发送到程序的正确信号,如果您希望生成内核转储
kill
是发送信号的正确命令行程序(它的名称当然不好,因为并非所有信号都会终止程序)

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


GCC表示:

POSIX/Unix说: Richard Stevens(UNIX环境中的高级编程)写道:

核心的生成是大多数Unix的一个实现特性。它不是POSIX.1的一部分

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

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


因此,如果您的目标是生成核心和停止,最好是选择一个信号,该信号的默认处理程序执行任务(SIGSEGV执行任务),如果您正在使用该信号,则重置该信号的默认处理程序,然后使用kill。

+1:kill-1通常用于发送SIGHUP,这通常会导致使用此功能编写的程序重新加载其配置。(例如:sendmail、init等)SIGQUIT是获得核心转储的一个。看看这个:不,这不好。这些信号都有特定的含义,程序对它们的响应也不同。它们不会全部杀死程序,也不会全部产生核心转储。+1但引用在这里会有很长一段路要走……POSIX对核心转储到底说了什么?好的。第二个文档标记为“A”,表示中止,可能会生成一个核心文件。不幸的是,应用程序可能已经为SIGQUIT安装了一个信号处理程序,以防止出现默认行为。在这种情况下,您将不再获得内核转储。然后,然后,然后认为合法的尝试滥用其他信号之一默认地生成一个核心转储(SigSeGv,Sigiar,…)+ 1的<代码>隆起< /代码>和<代码>异常> /代码>,这是更有意义的当目标是你自己。Emacs有一种方法来生成一个没有信号处理器的核心。在程序的构建过程中,它被用来保存一个新的emacs二进制文件,并且已经加载了elisp,这是一个可怕的黑客…@R。。上次我检查时,emacs的方法是通过了解可执行文件和核心文件格式,自己编写一个核心文件。XEmacs有一种更明智的方法——它将所有elisp代码/数据分配到自己管理的堆中(在
.data
部分),将其保存到磁盘,然后在运行时使用
mmap
MAP\u FIXED
将其映射回“堆”之上。