为什么Python在使用绝对路径执行时不会从引发的异常中退出?

时间:2012-10-12 19:15:15

标签: python exception-handling

已解决:重新启动计算机似乎已删除此问题。如果问题再次出现,我会更新。

我遇到一个问题,Python2.6在引发异常后挂起,特别是在使用绝对路径(foo.py)调用/home/user/bar/foo.py时。然后,我需要ctrl+c退出该计划。如果从bar目录中调用./foo.py或从根目录调用./home/user/bar/foo.py,程序将正确终止。

foo.py:

#!/usr/bin/env python2.6
print 'begin'
x = [0, 1, undefined]
print 'x'

#!/usr/bin/env python2.6
print 'begin'
raise Exception('stopping here')

我还可以提到sys.exit()可以正常工作,没有问题。

#!/usr/bin/env python2.6
import sys
print 'begin'
sys.exit(0)

未能终止程序的异常发生了什么?这可能是我的配置特有的。我应该从哪里开始寻找解决方案?

编辑:如果运行交互模式,execfile('/home/user/bar/foo.py')可以正常工作。此外,运行nohup /home/user/bar/foo.py &会导致必须终止的挂起过程。

运行CentOS版本6.3(最终版)。这个问题并不总是存在。这只是在一个月前的一个周末开始的(我当时没有使用机器)。

更新:使用GDB进行调试,回溯指向libpthread.so.0

#0  0x000000364340e890 in __connect_nocancel () from /lib64/libpthread.so.0
#1  0x00007ffff18960d8 in ?? () from /usr/lib64/python2.6/lib-dynload/_socketmodule.so
#2  0x00007ffff189815c in ?? () from /usr/lib64/python2.6/lib-dynload/_socketmodule.so
#3  0x00007ffff7d0a706 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#4  0x00007ffff7d0c797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0
#5  0x00007ffff7d0abe4 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#6  0x00007ffff7d0bccf in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#7  0x00007ffff7d0bccf in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#8  0x00007ffff7d0c797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0
#9  0x00007ffff7c9adb0 in ?? () from /usr/lib64/libpython2.6.so.1.0
#10 0x00007ffff7c70303 in PyObject_Call () from /usr/lib64/libpython2.6.so.1.0
#11 0x00007ffff7d04dd3 in PyEval_CallObjectWithKeywords () from /usr/lib64/libpython2.6.so.1.0
#12 0x00007ffff7d28cd2 in PyErr_PrintEx () from /usr/lib64/libpython2.6.so.1.0
#13 0x00007ffff7d29297 in PyRun_SimpleFileExFlags () from /usr/lib64/libpython2.6.so.1.0
#14 0x00007ffff7d35c32 in Py_Main () from /usr/lib64/libpython2.6.so.1.0
#15 0x000000364281ecdd in __libc_start_main () from /lib64/libc.so.6
#16 0x0000000000400649 in _start ()

有人知道这意味着什么吗?

4 个答案:

答案 0 :(得分:1)

这个问题一直困扰着我一段时间在RHEL 6机器上。在某些情况下,例外会导致挂起。事实上,我能够逐字记录您的代码并重现症状。

由于abrtd的答案,我确定安装了abrt-addon-python包,它将abrt_exception_handler.py放入site-packages位置,并在python启动期间调用。此文件将覆盖使用套接字与abrt守护程序联系的sys.excepthook函数。有关详细信息,请参阅ABRT Project Doc

我验证了在python调用中添加-S可以防止挂起。但是,这不是一个好的解决方案,因为-S选项会阻止在启动时导入所有站点包。

更好的解决方案是在python代码中添加以下内容:

import sys
sys.excepthook = sys.__excepthook__

恢复原始异常挂钩并防止挂起。

答案 1 :(得分:0)

  • 请检查sys.path是否有非绝对目录。
  • 您可以随时break into it with a debugger, e.g. gdb
  • 有时我在PYTHONSTARTUP中有东西,这会导致交互式解释器做一些不同的事情......
  • strace也可以成为你的朋友

答案 2 :(得分:0)

  • 重新启动机器。

鞠躬全能管理员的青睐,我能够让机器重新启动。一切都很好。如果问题再次出现,我会更新问题。

答案 3 :(得分:0)

我追踪了这个问题。它试图写入由abrtd打开的套接字。

重新启动abrtd'修复'此问题。这就是机器重启的原因。我没有找到问题的根本原因。