杀死一个Haskell二进制文件 [英] Killing a Haskell binary
问题描述
如果我按Ctrl + C,这会引发异常(总是在线程0中?)。如果你愿意,你可以抓住这个 - 或者更可能的是,运行一些清理工作然后重新抛出它。但通常的结果是让程序停顿,这种或那种方式。
现在假设我使用Unix kill
命令。据我所知, kill
基本上发送一个(可配置的)Unix信号给指定的进程。
Haskell RTS对此作出回应?它是否记录在某处?我想 发送 SIGTERM
与Ctrl + C具有相同的效果,但我不知道这个事实...
(当然,您可以使用 kill
发送与根本无关的信号。再一次,我会想象 RTS会忽略,例如 SIGHUP
或 SIGPWR
,但我不确定。)
在 ghc源代码在github上透露了 installDefaultSignals 函数:
void
initDefaultHandlers(void)
{
struct sigaction动作,oact;
//安装SIGINT处理程序
action.sa_handler = shutdown_handler;
sigemptyset(& action.sa_mask);
action.sa_flags = 0;如果(sigaction(SIGINT,& action,& oact)!= 0){
sysErrorBelch(警告:未能安装SIGINT处理程序),
;
}
#if defined(HAVE_SIGINTERRUPT)
siginterrupt(SIGINT,1); //是不是默认的? --SDM
#endif
//安装SIGFPE处理程序
//除了处理SIGINT外,还可以通过忽略它来处理SIGFPE。
//显然IEEE要求浮点异常被
//默认值忽略,但alpha-dec-osf3似乎没有这样做。
// SDM注释2/7/2002:这会导致
// //当一个整数除零时发生无限循环://
// don不会从浮点异常中恢复,并且
//程序会立即生成另一个。
#if 0
action.sa_handler = SIG_IGN;
sigemptyset(& action.sa_mask);
action.sa_flags = 0;如果(sigaction(SIGFPE,& action,& oact)!= 0){
sysErrorBelch(警告:未能安装SIGFPE处理程序),
;
}
#endif
#ifdef alpha_HOST_ARCH
ieee_set_fp_control(0);
#endif
//忽略SIGPIPE;请参阅#1619
//实际上,我们使用空信号处理程序而不是SIG_IGN,
//以便SIGPIPE在exec处重置为默认行为。
action.sa_handler = empty_handler;
sigemptyset(& action.sa_mask);
action.sa_flags = 0;如果(sigaction(SIGPIPE,& action,& oact)!= 0){
sysErrorBelch(warning:未能安装SIGPIPE处理程序),
;
}
set_sigtstp_action(rtsTrue);
}
从中可以看到GHC至少安装了SIGINT和SIGPIPE处理程序。我不知道是否有任何其他信号处理程序隐藏在源代码中。
If I press Ctrl+C, this throws an exception (always in thread 0?). You can catch this if you want - or, more likely, run some cleanup and then rethrow it. But the usual result is to bring the program to a halt, one way or another.
Now suppose I use the Unix kill
command. As I understand it, kill
basically sends a (configurable) Unix signal to the specified process.
How does the Haskell RTS respond to this? Is it documented somewhere? I would imagine that sending SIGTERM
would have the same effect as pressing Ctrl+C, but I don't know that for a fact...
(And, of course, you can use kill
to send signals that have nothing to do with killing at all. Again, I would imagine that the RTS would ignore, say, SIGHUP
or SIGPWR
, but I don't know for sure.)
Searching for "signal" in the ghc source code on github revealed the installDefaultSignals function:
void
initDefaultHandlers(void)
{
struct sigaction action,oact;
// install the SIGINT handler
action.sa_handler = shutdown_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGINT, &action, &oact) != 0) {
sysErrorBelch("warning: failed to install SIGINT handler");
}
#if defined(HAVE_SIGINTERRUPT)
siginterrupt(SIGINT, 1); // isn't this the default? --SDM
#endif
// install the SIGFPE handler
// In addition to handling SIGINT, also handle SIGFPE by ignoring it.
// Apparently IEEE requires floating-point exceptions to be ignored by
// default, but alpha-dec-osf3 doesn't seem to do so.
// Commented out by SDM 2/7/2002: this causes an infinite loop on
// some architectures when an integer division by zero occurs: we
// don't recover from the floating point exception, and the
// program just generates another one immediately.
#if 0
action.sa_handler = SIG_IGN;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGFPE, &action, &oact) != 0) {
sysErrorBelch("warning: failed to install SIGFPE handler");
}
#endif
#ifdef alpha_HOST_ARCH
ieee_set_fp_control(0);
#endif
// ignore SIGPIPE; see #1619
// actually, we use an empty signal handler rather than SIG_IGN,
// so that SIGPIPE gets reset to its default behaviour on exec.
action.sa_handler = empty_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGPIPE, &action, &oact) != 0) {
sysErrorBelch("warning: failed to install SIGPIPE handler");
}
set_sigtstp_action(rtsTrue);
}
From that, you can see that GHC installs at least SIGINT and SIGPIPE handlers. I don't know if there are any other signal handlers hidden in the source code.
这篇关于杀死一个Haskell二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!