如何使用subprocess和preexec_fn处理子进程的SIGFPE/SIGILL信号?
在Linux系统上,我有一个可执行文件,我想通过Python脚本来运行它。这个可执行文件在运行时会出现除以零的错误,而我似乎无法处理子进程发出的信号。我查了一些资料,发现preexec_fn应该能处理SIGFPE信号,但到现在为止都没有成功。
我使用的是Python 2.7。
我的代码是:
# b.py
import os
import subprocess
import signal
import sys
def pref_fun():
signal.signal(signal.SIGFPE,foo)
def foo(signal,frame):
print "Caught signal!"
sys.exit(0)
sub = subprocess.Popen(["a.out"], preexec_fn=pref_fun)
sub.wait()
v = sub.returncode
print "value: ", v
还有我的子进程:
a.c
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Now dividing by zero\n");
fflush(stdout);
double x = 5;
x= 5/0;
printf("oh no\n");
return 0;
}
我期待的输出是“捕获到信号!”,但我似乎没有得到这个结果。
2 个回答
0
确保你的Python是用这个配置选项编译的:
--with-fpectl 启用SIGFPE捕获
1
我担心我们不能这样做。虽然在子进程中安装了信号处理器,但当执行了 ./a.out
并用 exec()
替换时,原本有信号处理器的程序被新的程序替换了——所以子进程中就没有信号处理器了。不过,我们可以通过 os.WIFSIGNALED(v)
来检查子进程是否是因为信号而终止的,如果返回值是 True,我们可以用 os.WTERMSIG(v)
来获取具体是哪个信号导致的,之后我们可以在父进程中做一些处理。
不过,我在我的机器上使用 os.WTERMSIG(v)
得到了很奇怪的结果,发现实际的信号编号似乎是 v
的负数(我检查过 SIGSEGV
和 SIGFPE
),我不知道这是不是我机器的问题,反正希望这对你有帮助 :)。
import os
import subprocess
import signal
import sys
def pref_fun():
signal.signal(signal.SIGFPE,foo)
def foo(signal,frame):
print "Caught signal!"
sys.exit(0)
sub = subprocess.Popen(["./a.out"], preexec_fn=pref_fun)
sub.wait()
v = sub.returncode
print "value: ", v
print os.WIFSIGNALED(v)
print "signal:", os.WTERMSIG(v)
print "SIGFPE", signal.SIGFPE
输出结果是:
Now dividing by zero
value: -8
True
signal: 120
SIGFPE 8