强制应用程序核心转储并退出的正确方法是什么?
我刚刚遇到一些代码,它使用 Kill 系统调用向应用程序发送 SIGSEGV 信号。其背后的理由是,这将迫使应用程序进行核心转储并退出。这对我来说似乎很错误,这是正常做法吗?
I just came across some code which used the kill system call to send a SIGSEGV signal to an app. The rationale behind this was that this would force the app to core dump and quit. This seems so wrong to me, is this normal practice?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您希望生成核心转储,SIGQUIT 是发送到程序的正确信号。
kill
是发送信号的正确命令行程序(当然,它的命名很糟糕,因为并非所有信号都会杀死该程序)。请注意,您不应向程序发送随机信号,并非所有信号都会产生核心转储。其中许多将由程序本身处理,或者被消耗、被忽略,或者引发其他处理。因此发送 SIGSEGV 是错误的。
海湾合作委员会 说:
http://www.gnu.org/s/libc/manual /html_node/Termination-Signals.html
POSIX/Unix 说:
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal .h.html
SIGQUIT is the correct signal to send to a program if you wish to produce a core dump.
kill
is the correct command line program to send signals (it is of course poorly named, since not all signals will kill the program).Note, you should not send random signals to the program, not all of them will produce a core dump. Many of them will be handled by the program itself, either consumed, ignored, or induce other processing. Thus sending a SIGSEGV is wrong.
GCC Says:
http://www.gnu.org/s/libc/manual/html_node/Termination-Signals.html
POSIX/Unix Says:
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
是的。
kill
的命名有些错误——它可以发送任何信号。kill
有很多用途,但根本不会导致进程被终止!Yes.
kill
is somewhat misnamed -- it can send any signal. There are many uses forkill
which don't result in the process being killed at all!如果您想从另一个程序转储应用程序的核心,几乎唯一的方法就是通过信号。 SEGV 就适合这个。或者,您可以将调试器连接到程序并冻结它并查看它的寄存器等,而无需杀死它。
如果您想从应用程序内转储核心,有更好的方法可以做到这一点,例如通过assert()。
所以,不,将 SEGV 发送到程序并不是特别错误。您还可以发送 SIGILL 等非法指令或除以零信号。一切都很好。
If you want to make an application dump it's core from another program, pretty much the only way to do it is via a signal. SEGV would be fine for this. Alternatively you can hook a debugger up to the program and freeze it and view it's registers and such without killing it.
If you want to dump a core from within an application there are nicer ways to do it, like via an assert().
So, no, it's not particularly wrong to send a SEGV to a program. You could also send things like SIGILL for illegal instruction, or a divide by zero signal. It's all fine.
在 Unix/Linux 中执行此操作的方法是调用 abort(),它将向当前进程发送 SIGABORT。另一个选项是 raise() ,您可以在其中指定要发送到当前进程的信号。
The way to do it in Unix/Linux is to call abort() which will send SIGABORT to current process. The other option is raise() where you can specify what signal you want to send to current process.
Richard Stevens(_UNIX 环境中的高级编程)写道:
他列出了12个信号,其默认操作是用核心终止(ANSI:SIGABRT,SIGFPE,SIGILL,SIGSEGV,POSIX:SIGQUIT,其他:SIGBUS,SIGEMT,SIGIOT,SIGSYS,SIGTRAP,SIGXCPU,SIGXFSZ),所有这些信号都是可重写的(不可重写的两个信号是 SIGKILL 和 SIGSTOP)。
我从未见过一种不使用默认信号处理程序来生成核心的方法。
因此,如果您的目标是生成核心并停止,最好是选择一个信号,其默认处理程序可以完成这项工作(SIGSEGV 可以完成这项工作),如果您正在使用该信号,请重置该信号的默认处理程序,然后使用kill。
Richard Stevens (_Advanced Programming in the UNIX Environment) wrote:
He lists 12 signals whose default action is to terminate with a core (ANSI: SIGABRT, SIGFPE, SIGILL, SIGSEGV, POSIX: SIGQUIT, Other: SIGBUS, SIGEMT, SIGIOT, SIGSYS, SIGTRAP, SIGXCPU, SIGXFSZ), all of them are overwritable (the two signals which aren't overwritable are SIGKILL and SIGSTOP).
I've never seen a way to generate a core which isn't the use of a default signal handler.
So if your goal is to generate a core and stop, the best is to choose a signal whose default handler does the job (SIGSEGV does the job), reset the default handler for the signal if you are using it and then use kill.