问题描述
我看到一个看似无害的程序的 python 核心转储.我编写了以下代码来演示我的问题:
I am seeing python core dump for a seemingly harmless program. I have written following piece of code to demonstrate my problem:
proc = None def __signalHandler(signum, frame): print "In __signalHandler" if proc is not None: print "Send signal to BG proc" os.killpg(os.getpgid(proc.pid), signal.SIGINT) print "Wait for it to finish" proc.communicate() print "sys exit" sys.exit(130) signal.signal(signal.SIGINT, __signalHandler) # Start the process proc = subprocess.Popen(["a.out"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid) while proc.poll() is None: try: print proc.stdout.readline() except: print "Exception caught" print "Done!"
a.out 是打印语句并循环休眠的可执行文件:
a.out is a executable that prints statement and sleeps in a loop:
int main(int argc, char* argv[]) { for (int i = 0; i < 100; i++) { printf("Sleeping... "); std::cout.flush(); usleep(500000); } return 0; }
以下是我运行 python 代码时得到的输出(我运行 python 程序,然后按 Ctrl-C 以便调用信号处理程序):
Following is the output I get when I run the python code (I run the python program and then press Ctrl-C so that the signal handler gets invoked):
$ python sample.py Sleeping... Sleeping... Sleeping... ^CIn __signalHandler Send signal to BG proc Wait for it to finish sys exit Segmentation fault (core dumped)
有人知道为什么 python 核心转储吗?有没有什么办法解决这一问题?我的猜测是 sys.exit() 抛出的异常在某种程度上导致了问题.os._exit() 没有同样的问题.但是,我正在尝试找出这种行为背后的确切原因.
Does anyone have a clue why python core dumps? Is there any way to fix this? My guess is that the exception thrown from sys.exit() is somehow causing a problem. os._exit() doesnt have the same issue. However, I am trying to find out the exact reason behind this behaviour.
不管怎样,我使用的是 Python 2.7.3
For what it's worth, I am using Python 2.7.3
推荐答案
这个版本有效:中断顶层程序正确打印sys exit",子进程的输出逐行打印.
This version works: interrupting the top-level program correctly prints "sys exit", and output of the subprocess is printed line by line.
import os, signal, subprocess, sys proc = None def __signalHandler(signum, frame): print "In __signalHandler" if proc is not None: print "Send signal to BG proc" os.killpg(os.getpgid(proc.pid), signal.SIGINT) print "Wait for it to finish" proc.communicate() print "sys exit" sys.exit(130) signal.signal(signal.SIGINT, __signalHandler) # Start the process proc = subprocess.Popen('ping -c3 8.8.8.8'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid) while proc.poll() is None: try: print proc.stdout.readline(), except Exception as exc: print 'Exception caught: {}'.format(exc) print "Done!"
输出
$ python ./sub5.py PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=43 time=48.0 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=43 time=48.3 ms ^CIn __signalHandler Send signal to BG proc Wait for it to finish sys exit $ echo $? 130