You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Crash at interpreter exit when a thread is blocked in a qi call #9
When the Python interpreter exits while another thread is still blocked in a qi call, the process ends with a crash instead of exiting normally:
libc++abi: terminating due to uncaught exception of type qi::py::InterpreterFinalizingException: the interpreter is finalizing
Reproduction (qi 3.1.8, macOS, Python 3.14)
A daemon thread is blocked in Session.connect() against a server that accepts the TCP connection but never answers, so the connection never completes: see funwithagents/libqi#14. The main thread then exits.
importsocket, threading, qisrv=socket.socket(); srv.bind(("127.0.0.1", 0)); srv.listen(16)
conns= []
threading.Thread(target=lambda: [conns.append(srv.accept()[0]) for_initer(int, 1)], daemon=True).start()
s=qi.Session()
threading.Thread(target=lambda: s.connect(f"tcp://127.0.0.1:{srv.getsockname()[1]}"), daemon=True).start()
# the main thread exits here -> crash
Probable cause
During interpreter finalization, the bindings throw InterpreterFinalizingException when a thread tries to (re)acquire the GIL, presumably in GILAcquire, from qipython/pyguard.hpp / src/pyguard.cpp. When that happens in a context where the exception can't be caught (a destructor, a noexcept function, or a callback of a libqi thread), std::terminate is called.
Expected behaviour
The process exits normally. During finalization, the bindings should not throw from places where the exception can't propagate. For instance, they could leave the thread blocked or exit it quietly instead of throwing.
Activity