捕获“分段错误"崩溃子进程的消息:调用communication() 后没有输出和错误

问题描述

我在使用 subprocess 模块获取崩溃程序的输出时遇到问题.我正在使用 python2.7 和 subprocess 调用带有奇怪参数的程序以获得一些段错误为了调用程序,我使用以下代码:

I have problems using the subprocess module to obtain the output of crashed programs. I'm using python2.7 and subprocess to call a program with strange arguments in order to get some segfaults In order to call the program, I use the following code:

proc = (subprocess.Popen(called,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE))
out,err=proc.communicate()
print out,err

被调用的是一个包含程序名称和参数的列表(一个包含随机字节的字符串,除了子进程根本不喜欢的 NULL 字节)

called is a list containing the name of the program and the argument (a string containing random bytes except the NULL byte which subprocess doesn't like at all)

当程序没有崩溃时,代码会运行并向我显示 stdout 和 stderr,但是当它确实崩溃时,out 和 err 为空,而不是显示著名的分段错误".

The code behave and show me the stdout and stderr when the program doesn't crash, but when it does crash, out and err are empty instead of showing the famous "Segmentation fault".

我希望找到一种方法,即使程序崩溃也会出错.

I wish to find a way to obtain out and err even when the program crash.

我也试过 check_output/call/check_call 方法

I also tried the check_output / call / check_call methods

一些附加信息:

  • 我在 python 虚拟环境中的 Archlinux 64 位上运行这个脚本(这里不应该是重要的东西,但你永远不知道:p)

  • I'm running this script on an Archlinux 64 bits in a python virtual environment (shouldn't be something important here, but you never know :p)

段错误发生在我尝试运行的 C 程序中,是缓冲区溢出的结果

The segfault happens in the C program I'm trying to run and is a consequence of a buffer overflow

问题是当segfault发生时,我无法得到子进程发生了什么的输出

The problem is that when the segfault occurs, I can't get the output of what happened with subprocess

我得到正确的返回码:-11 (SIGSEGV)

I get the returncode right: -11 (SIGSEGV)

使用python我得到:

Using python i get:

  ./dumb2 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
  ('Exit code was:', -11) 
  ('Output was:', '') 
  ('Errors were:', '')

  • 在 python 之外我得到:

  • While outside python I get:

     ./dumb2 $(perl -e "print 'A'x50")  
     BEGINNING OF PROGRAM 
     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     END OF THE PROGRAM
     Segmentation fault (core dumped)
    

  • shell的返回值是一样的:echo $?返回 139 所以 -11 ($? & 128)

  • The return value of the shell is the same: echo $? returns 139 so -11 ($? & 128)


    解决方案

    回到这里:它就像 python3 的 subprocess 的魅力,如果你在 linux 上,有一个名为 subprocess32 的向后移植到 python2代码> 效果很好

    Came back here: it works like a charm with subprocess from python3 and if you are on linux, there is a backport to python2 called subprocess32 which does work quite well

    较旧的解决方案:我使用了 pexpect,它可以工作

    Older solution: I used pexpect and it works

    def cmd_line_call(name, args):
        child = pexpect.spawn(name, args)
        # Wait for the end of the output
        child.expect(pexpect.EOF) 
        out = child.before # we get all the data before the EOF (stderr and stdout)
        child.close() # that will set the return code for us
        # signalstatus and existstatus read as the same (for my purpose only)
        if child.exitstatus is None:
            returncode = child.signalstatus
        else:
            returncode = child.exitstatus
        return (out, returncode)
        
    

    PS:慢一点(因为它会产生一个伪 tty)

    PS: a little slower (because it spawns a pseudo tty)

  • 相关文章