Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Python exit from a raised exception when executed with an absolute path?

SOLVED: Rebooting the machine appears to have removed the issue. I will update if the problem returns.

I'm having an issue where Python2.6 hangs after an exception is raised, specifically when foo.py is called with an absolute path (/home/user/bar/foo.py). I am then required to ctrl+c out of the program. If called from within the bar directory as ./foo.py or from the root directory as ./home/user/bar/foo.py, the program terminates correctly.

foo.py:

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

or

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

I may also mention that a sys.exit() works fine, without issues.

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

What is happening to the exception that is failing to terminate the program? This is likely specific to my configuration. Where should I begin looking for a solution?

EDIT: execfile('/home/user/bar/foo.py') works fine if running interactive mode. Additionally, running nohup /home/user/bar/foo.py & results in a hanging process that must be killed.

Running CentOS release 6.3 (Final). This issue did not always exist. This only started about a month ago over a weekend (I was not using the machine at that time).

UPDATE: Debugging with GDB, the backtrace points to 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 ()

Anybody know what this means?

like image 613
ssjsonic1 Avatar asked Oct 12 '12 19:10

ssjsonic1


People also ask

Does raise error in Python stop execution?

When an exception is raised, no further statements in the current block of code are executed. Unless the exception is handled (described below), the interpreter will return directly to the interactive read-eval-print loop, or terminate entirely if Python was started with a file argument.

What is the point of raising an exception in Python?

Sometimes you want Python to throw a custom exception for error handling. You can do this by checking a condition and raising the exception, if the condition is True. The raised exception typically warns the user or the calling application.

How do you exit a Python program gracefully?

To stop code execution in Python you first need to import the sys object. After this you can then call the exit() method to stop the program running. It is the most reliable, cross-platform way of stopping code execution.


1 Answers

This exact issue has been biting me for awhile now on a RHEL 6 machine. In certain cases, Exceptions cause a hang. In fact, I was able to take your code verbatim and reproduce the symptom.

Thanks to the abrtd answer, I determined that abrt-addon-python package was installed which puts abrt_exception_handler.py into the site-packages location, and that is called during python startup. This file overrides the sys.excepthook function which contacts the abrt daemon using sockets. See ABRT Project Doc for more information.

I verified that adding -S to the python invocation prevents the hang. This is not a good solution, however, because the -S option prevents ALL site packages from being imported on startup.

A better solution is to add the following in your python code:

import sys
sys.excepthook = sys.__excepthook__

which restores the original exception hook and prevents the hang.

like image 146
Rich Drake Avatar answered Oct 08 '22 04:10

Rich Drake