运行 来自 Call 的程序没有 Seg Fault

Running Program from Call Doesn't Seg Fault

我的程序 writenotes 在我尝试写一个太长的注释时一直出现段错误。

./writenotes lolololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololo
[ * ] Writing notes
Segmentation fault

无论如何,我试图编写一个调用程序的 python 脚本,奇怪的是,从 python 脚本调用它不会带来段错误,我认为这是相当奇特

这是这段代码:

#!/usr/bin/python

from subprocess import call

call(["./writenotes", "lolololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololololo"])

哪个returns

[ * ] Writing notes

这是因为父处理还是类似的原因?通过子进程调用程序如何从段错误中保存程序?还有其他方法可以从遭受段错误的脚本中调用程序吗?

请注意,writenotes 程序是用 C 语言编写的。另一个脚本是 python。

您几乎肯定会发现您的 C 程序 正在 崩溃,但 Python 正在向您隐藏它。尝试使用:

print call(["./writenotes", "lolololol..."])

看看你得到什么作为 return 值。


例如,这个程序试图修改字符串文字,当运行正常转储核心时:

int main (void) {
    *"xyzzy" = 'X';
    return 0;
}

但是,当 运行 来自以下脚本时:

from subprocess import call
print call(["./testprog"])

我得到输出 -11,表明信号 11(通常是 SIGSEGV)被引发,根据讨论 Popen.returncode 的文档 subprocess.call()幕后用途:

A negative value -N indicates that the child was terminated by signal N (Unix only).


检查 return 代码的另一种方法是导入 check_callCalledProcessError 而不是 call,然后使用该函数。如果 return 代码不为零,它将引发异常。

如果您只调用一个可执行文件(在这种情况下只需获取 return 值),这可能并不那么重要,但是,如果您按顺序执行很多操作,则从整个过程中捕获异常组可能更具可读性。

将 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