Issue 1771260: Errors in site.py not reported properly (original) (raw)
(Ignore the p3yk dir name. This has been updated to the py3k branch.)
rhamph@factor:~/src/python-p3yk/build$ make object : type : TypeError refcount: 4 address : 0x8239f0c lost sys.stderr make: *** [sharedmods] Error 1
The root cause is that (due to some local modifications) site.py failed to load and gave an error. This can be easily duplicated by opening up Lib/site.py:main and putting 1/0 on the first line.
However, the ZeroDivisionError that should cause never gets printed. Python/pythonrun.c:initsite attempts to retrieve sys.stderr, which fails because site.py never got a chance to install it (!), then passes the NULL file object pointer to PyFile_WriteString, which turns that into a new exception (replacing the old one). initsite ignores the return value indicating the exception, instead clearing it, and the interpreter continues to load, no one the wiser.
Several other exceptions may happen and get squashed, I'm not sure.
Eventually, Python/sysmodule.c:sys_excepthook calls Python/pythonrun.c:PyErr_Display, which attempts to retrieve sys.stderr, and failing that calls _PyObject_Dump() on the exception (explaining the weird message). Oddly, there's a second if statement, which then prints the "lost sys.stderr" line.
Possible remedies:
- PyErr_Display's dump message is not very clear.
- initsite should go directly to stderr if it can't retrieve sys.stderr. Alternatively, since site.py is now more important, it could be changed into a fatal error. Yet another option is to explicitly check for sys.stderr even on success and make that alone into a fatal error.
- The error printing APIs could be modified to internalize the stderr retrieval. Upon failure they could print a brief "stderr unavailable; original exception was ..." message.
Following up on the possible remedies, I'm thinking PySys_WriteStderr could be extended to take file object as the first argument, and if null it writes to low-level stderr instead. That way the callers can add the message about "lost sys.stderr" themselves, rather than it being interspersed in their output.