什么时候在看门狗线程中引起段错误比正常退出以停止进程更可取?
When is it preferable to cause a segfault in a watchdog thread versus exiting normally to stop a process?
我想知道是否有 曾经 一个很好的理由以描述的方式退出看门狗线程,而不是以 exit()
退出。在我遇到的让我想起这个问题的代码中,段错误是由使用奇怪的行 *(char **)0 = "watchdog timeout";
.
取消引用空指针引起的
除非我弄错了,一个调用exit()
的线程会终止整个进程。我将段错误解释为错误,而不是预期的行为,但也许有时需要它。
void *watchdog_loop(void *arg) {
time_t now;
while(foo) {
sleep(1);
now = current_time();
if (watchdog_timeout && now - bar > watchdog_timeout) {
raise(SIGSEGV); //something went wrong
}
}
return NULL;
}
Is there ever a time that it would be more desirable to have a watchdog loop segfault intentionally, versus exiting nonzero?
引出未定义的行为是不可取的,示例代码正是这样做的。特别要注意的是,尽管在某些系统上它可能可靠地这样做,但不需要该代码来导致将段错误传递给进程。
然而,人们可能确实更喜欢通过信号而不是调用 exit()
来终止进程,以便在不执行任何应用程序或库清理代码的情况下实现终止。对于看门狗来说,这是一个合理的目标。然而,即使在那种情况下,
raise()
或 abort()
函数会明确地 导致将信号传递给进程。
SIGSEGV
似乎是一个奇怪的信号选择。 SIGABRT
、SIGTERM
或 SIGKILL
中的任何一个对我来说都更有意义。其中,
SIGKILL
不是由 C 语言规范指定的,而是由 POSIX (也许还有其他人)指定的。在 POSIX 系统上,SIGKILL
无法被阻塞或捕获,因此它是一个非常好的候选信号,可以尽可能快速和可靠地终止进程。
SIGABRT
被 abort()
函数使用,它也费尽心思试图克服程序对以这种方式终止的阻力。这是用于触发故意异常程序终止的最自然的标准函数。
SIGTERM
可以被捕获和/或阻塞,但与 SIGKILL
不同的是,它是由 C 语言规范定义的,因此更具可移植性。但我真的看不出比 SIGABRT
有任何优势,除非你 打算 允许它被处理。
另一种选择是 _exit()
(POSIX)或 _Exit()
(C99 或更高版本)。这些执行的关闭比您预期的通过信号终止更干净,但不执行大多数清理代码。打开的文件将被关闭,父进程将观察到进程以失败状态正常终止,而不是被信号杀死。
我想知道是否有 曾经 一个很好的理由以描述的方式退出看门狗线程,而不是以 exit()
退出。在我遇到的让我想起这个问题的代码中,段错误是由使用奇怪的行 *(char **)0 = "watchdog timeout";
.
除非我弄错了,一个调用exit()
的线程会终止整个进程。我将段错误解释为错误,而不是预期的行为,但也许有时需要它。
void *watchdog_loop(void *arg) {
time_t now;
while(foo) {
sleep(1);
now = current_time();
if (watchdog_timeout && now - bar > watchdog_timeout) {
raise(SIGSEGV); //something went wrong
}
}
return NULL;
}
Is there ever a time that it would be more desirable to have a watchdog loop segfault intentionally, versus exiting nonzero?
引出未定义的行为是不可取的,示例代码正是这样做的。特别要注意的是,尽管在某些系统上它可能可靠地这样做,但不需要该代码来导致将段错误传递给进程。
然而,人们可能确实更喜欢通过信号而不是调用 exit()
来终止进程,以便在不执行任何应用程序或库清理代码的情况下实现终止。对于看门狗来说,这是一个合理的目标。然而,即使在那种情况下,
raise()
或abort()
函数会明确地 导致将信号传递给进程。SIGSEGV
似乎是一个奇怪的信号选择。SIGABRT
、SIGTERM
或SIGKILL
中的任何一个对我来说都更有意义。其中,SIGKILL
不是由 C 语言规范指定的,而是由 POSIX (也许还有其他人)指定的。在 POSIX 系统上,SIGKILL
无法被阻塞或捕获,因此它是一个非常好的候选信号,可以尽可能快速和可靠地终止进程。SIGABRT
被abort()
函数使用,它也费尽心思试图克服程序对以这种方式终止的阻力。这是用于触发故意异常程序终止的最自然的标准函数。SIGTERM
可以被捕获和/或阻塞,但与SIGKILL
不同的是,它是由 C 语言规范定义的,因此更具可移植性。但我真的看不出比SIGABRT
有任何优势,除非你 打算 允许它被处理。
另一种选择是
_exit()
(POSIX)或_Exit()
(C99 或更高版本)。这些执行的关闭比您预期的通过信号终止更干净,但不执行大多数清理代码。打开的文件将被关闭,父进程将观察到进程以失败状态正常终止,而不是被信号杀死。