{LYN-4372} fix for Python exit crash (#1600)

There is a crash when sys.exit() was being called since embedded Python
should not have control of the application lifetime. The Py_InspectFlag
puts the Python VM into 'inspection mode' which prevents the app
shutdown when any sys.exit() is invoked.

Notes:
* skips 'regset' extra command line in PythonBindingsExample
* added methods for handling PythonBindingsExample errors

Test: added Application_SystemExit_Blocked and
fixed up Application_Run_Fails now is Application_Run_Works
main
jackalbe 5 years ago committed by GitHub
parent 9d9ff751b6
commit 580bd11715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -28,6 +28,18 @@ namespace PythonBindingsExample
void TearDown();
bool RunWithParameters(const ApplicationParameters& params);
inline void GetErrorCount(int& exceptionCount, int& errorCount)
{
exceptionCount = m_pythonExceptionCount;
errorCount = m_pythonErrorCount;
}
inline void ResetErrorCount()
{
m_pythonExceptionCount = 0;
m_pythonErrorCount = 0;
}
protected:
////////////////////////////////////////////////////////////////////////////////////////////
// TraceMessageBus

@ -60,6 +60,10 @@ PythonBindingsExample.exe --file path/to/file.py --arg one --arg two
{
m_interactiveMode = true;
}
else if (switchItem.m_option.starts_with("regset"))
{
// skip
}
else
{
AZ_Warning("python_app", false, "Unknown switch %s \n", switchItem.m_option.c_str());

@ -58,9 +58,9 @@ namespace PythonBindingsExample
AZStd::unique_ptr<PythonBindingsExample::Application> PythonBindingsExampleTest::s_application;
TEST_F(PythonBindingsExampleTest, Application_Run_Fails)
TEST_F(PythonBindingsExampleTest, Application_Run_Works)
{
EXPECT_FALSE(s_application->Run());
EXPECT_TRUE(s_application->Run());
}
TEST_F(PythonBindingsExampleTest, Application_RunWithParameters_Works)
@ -90,4 +90,37 @@ namespace PythonBindingsExample
EXPECT_TRUE(s_application->RunWithParameters(params));
}
TEST_F(PythonBindingsExampleTest, Application_SystemExit_Blocked)
{
int exceptions = 0;
int errors = 0;
s_application->GetErrorCount(exceptions, errors);
ASSERT_EQ(exceptions, 0);
ASSERT_EQ(errors, 0);
// expects a clean "error" from this statement
// the whole program should not exit()
{
ApplicationParameters params;
params.m_pythonStatement = "import sys; sys.exit(0)";
EXPECT_FALSE(s_application->RunWithParameters(params));
s_application->GetErrorCount(exceptions, errors);
EXPECT_EQ(exceptions, 0);
EXPECT_GE(errors, 1);
}
s_application->ResetErrorCount();
// should be able to run more statements
{
ApplicationParameters params;
params.m_pythonStatement = "import sys";
EXPECT_TRUE(s_application->RunWithParameters(params));
s_application->GetErrorCount(exceptions, errors);
EXPECT_EQ(exceptions, 0);
EXPECT_EQ(errors, 0);
}
}
}

@ -496,6 +496,7 @@ namespace EditorPythonBindings
// ignore system location for sites site-packages
Py_IsolatedFlag = 1; // -I - Also sets Py_NoUserSiteDirectory. If removed PyNoUserSiteDirectory should be set.
Py_IgnoreEnvironmentFlag = 1; // -E
Py_InspectFlag = 1; // unhandled SystemExit will terminate the process unless Py_InspectFlag is set
const bool initializeSignalHandlers = true;
pybind11::initialize_interpreter(initializeSignalHandlers);

Loading…
Cancel
Save