关于此问题还有一些注意事项 - 问题仍未解决......首先:
问题 6294:改进关闭异常忽略消息 - Python 跟踪器 http://bugs.python.org/issue6294#msg89442
这个错误信息是在PyErr_WriteUnraisable中生成的,即
从许多上下文中调用,包括 __del__ 方法。 __del__ 方法
在关闭期间调用很可能是产生错误的原因
正在谈论,但据我所知 __del__ 方法无法
特别是知道它是在关闭期间被调用的。所以
对该消息提出的修复不起作用。 [...]
然而,因为这是一条消息,所以你甚至无法捕获它
更改它应该是完全安全的。
嗯,谢谢你的这个消息,你不能陷入困境,非常方便。我相信这在某种程度上与忽略打印到 stderr 的异常del() - 堆栈溢出 https://stackoverflow.com/questions/13977970/ignore-exceptions-printed-to-stderr-in-del,尽管那篇文章(显然)谈论的是定制__del__
方法。
使用以下一些资源:
- 使用 Python 的 sys.settrace() 既有趣又有利可图 |回忆的:属于或关于回忆的 http://reminiscential.wordpress.com/2012/04/17/use-pythons-sys-settrace-for-fun-and-for-profit/
- Python全局异常处理 - 代码日志 https://stackoverflow.com/questions/6598053/python-global-exception-handling
...我修改了脚本,所以我重载了所有可能的处理程序,以查看是否没有空间可以“处理”此异常,这样它就不会被“忽略”:
import sys
import atexit
import signal
import inspect, pprint
def signalPIPE_handler(signal, frame):
sys.stderr.write('signalPIPE_handler!'+str(sys.exc_info())+'\n')
return #sys.exit(0) # just return doesn't exit!
signal.signal(signal.SIGPIPE, signalPIPE_handler)
_old_excepthook = sys.excepthook
def myexcepthook(exctype, value, intraceback):
import sys
import traceback
sys.stderr.write("myexcepthook\n")
if exctype == IOError:
sys.stderr.write(" IOError intraceback:\n")
traceback.print_tb(intraceback)
else:
_old_excepthook(exctype, value, intraceback)
sys.excepthook = myexcepthook
def _trace(frame, event, arg):
if event == 'exception':
while frame is not None:
filename, lineno = frame.f_code.co_filename, frame.f_lineno
sys.stderr.write("_trace exc frame: " + filename \
+ " " + str(lineno) + " " + str(frame.f_trace) + str(arg) + "\n")
if arg[0] == IOError:
myexcepthook(arg[0], arg[1], arg[2])
frame = frame.f_back
return _trace
sys.settrace(_trace)
def exiter():
import sys
sys.stderr.write("Exiting\n")
atexit.register(exiter)
def main():
teststr = "Hello " * 5
try:
sys.stdout.write(teststr + "\n")
sys.stdout.flush()
except IOError:
sys.stderr.write("Exc: " + str(sys.exc_info()[0]) + "\n")
#sys.exit(0)
if __name__ == "__main__":
main()
请注意此脚本运行方式的差异:
$ python2.7 testprint.py | echo
signalPIPE_handler!(None, None, None)
_trace exc frame: testprint.py 44 <function _trace at 0xb748e5dc>(<type 'exceptions.IOError'>, (32, 'Broken pipe'), <traceback object at 0xb748acac>)
myexcepthook
IOError intraceback:
File "testprint.py", line 44, in main
sys.stdout.flush()
_trace exc frame: testprint.py 51 None(<type 'exceptions.IOError'>, (32, 'Broken pipe'), <traceback object at 0xb748acac>)
myexcepthook
IOError intraceback:
File "testprint.py", line 44, in main
sys.stdout.flush()
Exc: <type 'exceptions.IOError'>
Exiting
$ python3.2 testprint.py | echo
signalPIPE_handler!(None, None, None)
_trace exc frame: testprint.py 44 <function _trace at 0xb74247ac>(<class 'IOError'>, (32, 'Broken pipe'), <traceback object at 0xb747393c>)
myexcepthook
IOError intraceback:
File "testprint.py", line 44, in main
sys.stdout.flush()
_trace exc frame: testprint.py 51 None(<class 'IOError'>, (32, 'Broken pipe'), <traceback object at 0xb747393c>)
myexcepthook
IOError intraceback:
File "testprint.py", line 44, in main
sys.stdout.flush()
Exc: <class 'IOError'>
signalPIPE_handler!(None, None, None)
Exiting
signalPIPE_handler!(None, None, None)
Exception IOError: (32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored
注意signalPIPE_handler
在 Python 3 中运行速度是原来的两倍!我想,如果Python中有某种“异常队列”,我可以“偷看”它,并删除其中剩余的事件signalPIPE_handler
,从而抑制Exception ... ignored
消息...但我不知道有这样的事情。
最后,当尝试使用以下资源进行调试时,这些资源非常有用gdb
:
- c - gdb - 使用管道调试 - 代码日志 https://stackoverflow.com/questions/1456253/gdb-debugging-with-pipe
- linux - 使用gdb在指定的可执行文件之外单步执行汇编代码会导致错误“无法找到当前函数的边界” - 堆栈内存溢出 https://stackoverflow.com/questions/2420813/using-gdb-to-single-step-assembly-code-outside-specified-executable-causes-error
...因为我没有python3-dbg
,所有这些都简化为逐步执行机器指令(layout asm
in gdb
,然后 Ctrl-X + A),这并没有告诉我太多信息。但这是如何触发问题的gdb
:
在一个终端中:
$ mkfifo foo
$ gdb python3.2
...
Reading symbols from /usr/bin/python3.2...(no debugging symbols found)...done.
(gdb) run testprint.py > foo
Starting program: /usr/bin/python3.2 testprint.py > foo
这里它会阻塞;在同一目录中的另一个终端中执行以下操作:
$ echo <foo
...然后返回到第一个终端 - 您应该看到:
...
Starting program: /usr/bin/python3.2 testprint.py > foo
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Program received signal SIGPIPE, Broken pipe.
0x0012e416 in __kernel_vsyscall ()
(gdb) bt
#0 0x0012e416 in __kernel_vsyscall ()
#1 0x0013c483 in __write_nocancel () from /lib/i386-linux-gnu/libpthread.so.0
#2 0x0815b549 in ?? ()
#3 0x08170507 in ?? ()
#4 0x08175e43 in PyObject_CallMethodObjArgs ()
#5 0x0815df21 in ?? ()
#6 0x0815f94e in ?? ()
#7 0x0815fb05 in ?? ()
#8 0x08170507 in ?? ()
#9 0x08175cb1 in _PyObject_CallMethod_SizeT ()
#10 0x08164851 in ?? ()
#11 0x080a3a36 in PyEval_EvalFrameEx ()
#12 0x080a3a53 in PyEval_EvalFrameEx ()
#13 0x080a43c8 in PyEval_EvalCodeEx ()
#14 0x080a466f in PyEval_EvalCode ()
#15 0x080c6e9d in PyRun_FileExFlags ()
#16 0x080c70c0 in PyRun_SimpleFileExFlags ()
#17 0x080db537 in Py_Main ()
#18 0x0805deee in main ()
(gdb) finish
Run till exit from #0 0x0012e416 in __kernel_vsyscall ()
0x0013c483 in __write_nocancel () from /lib/i386-linux-gnu/libpthread.so.0
...
不幸的是,我现在无法从源代码构建 Python3 并对其进行调试;所以我希望得到了解的人的答复:)
Cheers!