In mjpython, check the result of Py_InitializeFromConfig.

This is to properly handle the case where the interpreter wants to exit immediately, e.g. when `mjpython --version` is run.

Currently, we call `PyGILState_Ensure` regardless of the result of `Py_InitializeFromConfig` resulting in a segfault, as in issue #2870.

PiperOrigin-RevId: 869652555
Change-Id: I3a898279eb8aa25afbaece904cfdcc4fdcc92972
This commit is contained in:
Saran Tunyasuvunakool
2026-02-13 03:43:58 -08:00
committed by Copybara-Service
parent 881544c0c5
commit 496f6b47fc
+18 -3
View File
@@ -57,6 +57,8 @@ struct {
CPYTHON_FN(PyGILState_Ensure);
CPYTHON_FN(PyGILState_Release);
CPYTHON_FN(PyRun_SimpleStringFlags);
CPYTHON_FN(PyStatus_Exception);
CPYTHON_FN(Py_ExitStatusException);
CPYTHON_FN(Py_FinalizeEx);
CPYTHON_FN(Py_InitializeFromConfig);
CPYTHON_FN(Py_RunMain);
@@ -65,7 +67,7 @@ struct {
#undef CPYTHON_FN
} cpython;
std::atomic_bool py_initialized = false;
std::atomic_bool py_initialized;
struct Args {
int argc;
@@ -80,8 +82,20 @@ void* mjpython_pymain(void* vargs) {
// Initialize the Python interpreter.
PyConfig config;
cpython.PyConfig_InitPythonConfig(&config);
cpython.PyConfig_SetBytesArgv(&config, args->argc, args->argv);
cpython.Py_InitializeFromConfig(&config);
{
PyStatus status = cpython.PyConfig_SetBytesArgv(&config, args->argc, args->argv);
if (cpython.PyStatus_Exception(status)) {
// Calls exit() which aborts the entire process.
cpython.Py_ExitStatusException(status);
}
}
{
PyStatus status = cpython.Py_InitializeFromConfig(&config);
if (cpython.PyStatus_Exception(status)) {
// Calls exit() which aborts the entire process.
cpython.Py_ExitStatusException(status);
}
}
cpython.PyConfig_Clear(&config);
// Set up the condition variable to pass control back to the macOS main thread.
@@ -205,6 +219,7 @@ _mjpython_init()
} // namespace
int main(int argc, char** argv) {
py_initialized.store(false);
const char* libpython_path = getenv("MJPYTHON_LIBPYTHON");
if (!libpython_path || !libpython_path[0]) {
std::cerr << "This binary must be launched via the mjpython.py script.\n";