diff options
Diffstat (limited to 'Programs/_testembed.c')
-rw-r--r-- | Programs/_testembed.c | 110 |
1 files changed, 54 insertions, 56 deletions
diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 6f6d0cae580..577da65c7cd 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -8,6 +8,7 @@ #include <Python.h> #include "pycore_initconfig.h" // _PyConfig_InitCompatConfig() #include "pycore_runtime.h" // _PyRuntime +#include "pycore_lock.h" // PyEvent #include "pycore_pythread.h" // PyThread_start_joinable_thread() #include "pycore_import.h" // _PyImport_FrozenBootstrap #include <inttypes.h> @@ -80,7 +81,7 @@ static void init_from_config_clear(PyConfig *config) } -static void _testembed_Py_InitializeFromConfig(void) +static void _testembed_initialize(void) { PyConfig config; _PyConfig_InitCompatConfig(&config); @@ -88,16 +89,10 @@ static void _testembed_Py_InitializeFromConfig(void) init_from_config_clear(&config); } -static void _testembed_Py_Initialize(void) -{ - Py_SetProgramName(PROGRAM_NAME); - Py_Initialize(); -} - static int test_import_in_subinterpreters(void) { - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); PyThreadState_Swap(Py_NewInterpreter()); return PyRun_SimpleString("import readline"); // gh-124160 } @@ -131,7 +126,7 @@ static int test_repeated_init_and_subinterpreters(void) for (int i=1; i <= INIT_LOOPS; i++) { printf("--- Pass %d ---\n", i); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); mainstate = PyThreadState_Get(); PyEval_ReleaseThread(mainstate); @@ -197,7 +192,7 @@ static int test_repeated_init_exec(void) code = main_argv[i+2]; } - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); int err = PyRun_SimpleString(code); Py_Finalize(); if (err) { @@ -217,7 +212,7 @@ static int test_repeated_simple_init(void) fprintf(stderr, "--- Loop #%d ---\n", i); fflush(stderr); - _testembed_Py_Initialize(); + _testembed_initialize(); Py_Finalize(); printf("Finalized\n"); // Give test_embed some output to check } @@ -301,24 +296,8 @@ static int test_pre_initialization_api(void) /* the test doesn't support custom memory allocators */ putenv("PYTHONMALLOC="); - /* Leading "./" ensures getpath.c can still find the standard library */ - _Py_EMBED_PREINIT_CHECK("Checking Py_DecodeLocale\n"); - wchar_t *program = Py_DecodeLocale("./spam", NULL); - if (program == NULL) { - fprintf(stderr, "Fatal error: cannot decode program name\n"); - return 1; - } - _Py_EMBED_PREINIT_CHECK("Checking Py_SetProgramName\n"); - Py_SetProgramName(program); - - _Py_EMBED_PREINIT_CHECK("Checking !Py_IsInitialized pre-initialization\n"); - if (Py_IsInitialized()) { - fprintf(stderr, "Fatal error: initialized before initialization!\n"); - return 1; - } - _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n"); - Py_Initialize(); + _testembed_initialize(); _Py_EMBED_PREINIT_CHECK("Checking Py_IsInitialized post-initialization\n"); if (!Py_IsInitialized()) { @@ -340,9 +319,6 @@ static int test_pre_initialization_api(void) fprintf(stderr, "Fatal error: still initialized after finalization!\n"); return 1; } - - _Py_EMBED_PREINIT_CHECK("Freeing memory allocated by Py_DecodeLocale\n"); - PyMem_RawFree(program); return 0; } @@ -384,7 +360,7 @@ static int test_pre_initialization_sys_options(void) dynamic_xoption = NULL; _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n"); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); _Py_EMBED_PREINIT_CHECK("Check sys module contents\n"); PyRun_SimpleString( "import sys; " @@ -431,7 +407,7 @@ static int test_bpo20891(void) return 1; } - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &lock); if (thrd == PYTHREAD_INVALID_THREAD_ID) { @@ -454,7 +430,7 @@ static int test_bpo20891(void) static int test_initialize_twice(void) { - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); /* bpo-33932: Calling Py_Initialize() twice should do nothing * (and not crash!). */ @@ -472,7 +448,7 @@ static int test_initialize_pymain(void) L"print(f'Py_Main() after Py_Initialize: " L"sys.argv={sys.argv}')"), L"arg2"}; - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); /* bpo-34008: Calling Py_Main() after Py_Initialize() must not crash */ Py_Main(Py_ARRAY_LENGTH(argv), argv); @@ -495,7 +471,7 @@ dump_config(void) static int test_init_initialize_config(void) { - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); dump_config(); Py_Finalize(); return 0; @@ -569,9 +545,6 @@ static int test_init_global_config(void) putenv("PYTHONUTF8=0"); Py_UTF8Mode = 1; - /* Test initialization from global configuration variables (Py_xxx) */ - Py_SetProgramName(L"./globalvar"); - /* Py_IsolatedFlag is not tested */ Py_NoSiteFlag = 1; Py_BytesWarningFlag = 1; @@ -604,7 +577,7 @@ static int test_init_global_config(void) /* FIXME: test Py_LegacyWindowsFSEncodingFlag */ /* FIXME: test Py_LegacyWindowsStdioFlag */ - Py_Initialize(); + _testembed_initialize(); dump_config(); Py_Finalize(); return 0; @@ -651,8 +624,8 @@ static int test_init_from_config(void) putenv("PYTHONTRACEMALLOC=0"); config.tracemalloc = 2; - putenv("PYTHONPROFILEIMPORTTIME=0"); - config.import_time = 1; + putenv("PYTHONPROFILEIMPORTTIME=1"); + config.import_time = 2; putenv("PYTHONNODEBUGRANGES=0"); config.code_debug_ranges = 0; @@ -666,7 +639,6 @@ static int test_init_from_config(void) putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix"); - Py_SetProgramName(L"./globalvar"); config_set_string(&config, &config.program_name, L"./conf_program_name"); wchar_t* argv[] = { @@ -853,7 +825,7 @@ static int test_init_compat_env(void) /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; set_all_env_vars(); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); dump_config(); Py_Finalize(); return 0; @@ -889,7 +861,7 @@ static int test_init_env_dev_mode(void) /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; set_all_env_vars_dev_mode(); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); dump_config(); Py_Finalize(); return 0; @@ -906,7 +878,7 @@ static int test_init_env_dev_mode_alloc(void) #else putenv("PYTHONMALLOC=mimalloc"); #endif - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); dump_config(); Py_Finalize(); return 0; @@ -1246,7 +1218,7 @@ static int test_open_code_hook(void) } Py_IgnoreEnvironmentFlag = 0; - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); result = 0; PyObject *r = PyFile_OpenCode("$$test-filename"); @@ -1310,7 +1282,7 @@ static int _test_audit(Py_ssize_t setValue) Py_IgnoreEnvironmentFlag = 0; PySys_AddAuditHook(_audit_hook, &sawSet); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); if (PySys_Audit("_testembed.raise", NULL) == 0) { printf("No error raised"); @@ -1369,7 +1341,7 @@ static int test_audit_tuple(void) // we need at least one hook, otherwise code checking for // PySys_AuditTuple() is skipped. PySys_AddAuditHook(_audit_hook, &sawSet); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); ASSERT(!PyErr_Occurred(), 0); @@ -1422,7 +1394,7 @@ static int test_audit_subinterpreter(void) { Py_IgnoreEnvironmentFlag = 0; PySys_AddAuditHook(_audit_subinterpreter_hook, NULL); - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); Py_NewInterpreter(); Py_NewInterpreter(); @@ -2166,13 +2138,13 @@ static int test_unicode_id_init(void) }; // Initialize Python once without using the identifier - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); Py_Finalize(); // Now initialize Python multiple times and use the identifier. // The first _PyUnicode_FromId() call initializes the identifier index. for (int i=0; i<3; i++) { - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); PyObject *str1, *str2; @@ -2195,7 +2167,7 @@ static int test_unicode_id_init(void) static int test_init_main_interpreter_settings(void) { - _testembed_Py_Initialize(); + _testembed_initialize(); (void) PyRun_SimpleStringFlags( "import _testinternalcapi, json; " "print(json.dumps(_testinternalcapi.get_interp_settings(0)))", @@ -2206,7 +2178,7 @@ static int test_init_main_interpreter_settings(void) static void do_init(void *unused) { - _testembed_Py_Initialize(); + _testembed_initialize(); Py_Finalize(); } @@ -2331,7 +2303,7 @@ unwrap_allocator(PyMemAllocatorEx *allocator) static int test_get_incomplete_frame(void) { - _testembed_Py_InitializeFromConfig(); + _testembed_initialize(); PyMemAllocatorEx allocator; wrap_allocator(&allocator); // Force an allocation with an incomplete (generator) frame: @@ -2341,6 +2313,32 @@ test_get_incomplete_frame(void) return result; } +static void +do_gilstate_ensure(void *event_ptr) +{ + PyEvent *event = (PyEvent *)event_ptr; + // Signal to the calling thread that we've started + _PyEvent_Notify(event); + PyGILState_Ensure(); // This should hang + assert(NULL); +} + +static int +test_gilstate_after_finalization(void) +{ + _testembed_initialize(); + Py_Finalize(); + PyThread_handle_t handle; + PyThread_ident_t ident; + PyEvent event = {0}; + if (PyThread_start_joinable_thread(&do_gilstate_ensure, &event, &ident, &handle) < 0) { + return -1; + } + PyEvent_Wait(&event); + // We're now pretty confident that the thread went for + // PyGILState_Ensure(), but that means it got hung. + return PyThread_detach_thread(handle); +} /* ********************************************************* * List of test cases and the function that implements it. @@ -2431,7 +2429,7 @@ static struct TestCase TestCases[] = { {"test_frozenmain", test_frozenmain}, #endif {"test_get_incomplete_frame", test_get_incomplete_frame}, - + {"test_gilstate_after_finalization", test_gilstate_after_finalization}, {NULL, NULL} }; |