runtime: flush stdout and stderr file descriptors at exit - #38
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Code reviewFound 2 new issues — see the inline comments. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Code reviewFound 2 new issues — see the inline comments. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Code reviewFound 3 new issues — see the inline comments. |
Uh oh!
There was an error while loading. Please reload this page.
Code reviewFound 1 new issue — see the inline comment. |
Uh oh!
There was an error while loading. Please reload this page.
Code reviewFound 1 new issue — see the inline comments. |
| PyResult<PyObject *> isatty() | ||
| { | ||
| return m_buffer->get_method(PyString::create("isatty").unwrap()).and_then([](auto *isatty) { | ||
| return isatty->call(nullptr, nullptr); | ||
| }); | ||
| } |
There was a problem hiding this comment.
isatty() dereferences m_buffer with no initialization check (bug)
m_buffer is only set in init(), and TextIOWrapper.__new__ allocates without initializing it, so _io.TextIOWrapper.__new__(_io.TextIOWrapper).isatty() (or type(sys.stdout).__new__(type(sys.stdout)).isatty()) null-derefs and crashes. Previously isatty() resolved to the inherited IOBase::isatty, which safely returns False after a check_closed() — so this is a new crash path on a call that was previously safe, not just a pre-existing hazard. BufferedWriter in this same PR guards the analogous case via check_initialized().
Code reviewFound 1 new issue — see the inline comments. |
| PyResult<std::monostate> Interpreter::finalise() | ||
| { | ||
| // TODO: capture exceptions, and raise last one | ||
| for (auto [callback, args] : m_callbacks) { | ||
| [[maybe_unused]] auto result = callback->call(args, nullptr); | ||
| } | ||
| return Ok(std::monostate{}); |
There was a problem hiding this comment.
finalise() discards the result of every exit callback ([[maybe_unused]] auto result = ...) and always returns Ok. The caller in BytecodeProgram.cpp also discards finalise()'s return value, so the process exit code depends only on the main function's result. Since this same PR makes print() default to flush=False and ties sys.stdout line-buffering to isatty(), a flush failure during exit (e.g. EPIPE on a closed pipe, ENOSPC) is now silently swallowed instead of surfacing as a Python error — output can be silently truncated while the process still exits 0. (bug)
Code reviewFound 1 new issue — see the inline comment. |
Uh oh!
There was an error while loading. Please reload this page.
No description provided.