当我尝试写一个太长的音符时,我的程序writenotes
会出现段错误。
./writenotes lolololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololo
[ * ] Writing notes
Segmentation fault
无论如何,我试图编写一个调用该程序的python脚本并且奇怪地从python脚本中调用它并不会带来一个seg错误,我认为这个错误很奇怪。
见下这段代码:
#!/usr/bin/python
from subprocess import call
call(["./writenotes", "lolololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololo"])
返回
[ * ] Writing notes
这是因为父处理还是类似的事情?如何通过子进程调用程序从segfault中保存程序呢?是否还有其他方法可以从遭受seg故障的脚本调用程序?
作为一个注释,writenotes程序是用C语言编写的。另一个脚本是python。
答案 0 :(得分:2)
您几乎肯定会发现您的C程序 崩溃,但Python正在隐藏这一点。请尝试使用:
print call(["./writenotes", "lolololol..."])
并查看您获得的返回值。
例如,此程序尝试修改字符串文字,并在正常运行时转储核心:
int main (void) {
*"xyzzy" = 'X';
return 0;
}
但是,从以下脚本运行时:
from subprocess import call
print call(["./testprog"])
我得到了输出-11
,表明信号11
(通常为SIGSEGV
)被引发,根据Popen.returncode
subprocess.call()
所使用的文档封面:
负值
-N
表示孩子被信号N
终止(仅限Unix)。
检查返回代码的另一种方法是导入check_call
和CalledProcessError
而不是call
,然后使用该功能。如果返回码非零,它将引发异常。
如果您只调用一个可执行文件(在这种情况下只获得返回值),那可能就不那么重要了,但是,如果您按顺序执行了大量操作,则从中捕获异常整个小组可能更具可读性。
将C程序更改为仅在第一个参数为3
时崩溃:
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[]) {
if (argc > 1) {
printf ("hello there %s\n", argv[1]);
if (strcmp (argv[1], "3") == 0)
*"xyzzy" = 'X';
}
return 0;
}
以及使用几个不同参数调用它的脚本:
from subprocess import check_call, CalledProcessError
try:
check_call(["./testprog", "0"])
check_call(["./testprog", "1"])
check_call(["./testprog", "2"])
check_call(["./testprog", "3"])
check_call(["./testprog", "4"])
check_call(["./testprog", "5"])
check_call(["./testprog", "6"])
check_call(["./testprog", "7"])
check_call(["./testprog", "8"])
check_call(["./testprog", "9"])
except CalledProcessError as e:
print e.cmd, "failed with", e.returncode
else:
print "Everything went well"
显示在行动中:
hello there 0
hello there 1
hello there 2
hello there 3
['./testprog', '3'] failed with -11