GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — Some builtin single phase modules do get loaded into subinterpreters which do not support them · Issue #119450 · python/cpython Closed Labels topic-subinterpreterstype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error DescriptionBug description:If a subinterpreter is started with PyInterpreterConfig cfg = { ... .check_multi_interp_extensions = 1, }; Py_NewInterpreterFromConfig(&ts, &cfg); I expect that no single phase module is allowed to be loaded. This works for all self build modules and with most builtin ones, but not all. Some modules i found to be misbehaving are e.g. datetime, tracemalloc. This can easily cause a crash: #include <Python.h> #include <assert.h> // make subinterpreter from config PyThreadState* make_sub(PyInterpreterConfig* config) { PyThreadState* sub = NULL; PyStatus status = Py_NewInterpreterFromConfig(&sub, config); if (PyStatus_Exception(status)) { return NULL; } return sub; } // create an isolated subinterpreter, then load a module with name 'name' void sub_import(PyThreadState* main, const char* name) { PyEval_AcquireThread(main); PyInterpreterConfig config = { .use_main_obmalloc = 0, .allow_fork = 0, .allow_exec = 0, .allow_threads = 1, .allow_daemon_threads = 0, .check_multi_interp_extensions = 1, .gil = PyInterpreterConfig_OWN_GIL, }; PyThreadState* sub = make_sub(&config); assert(sub); PyObject* module = PyImport_ImportModule(name); printf("Loaded: %s\n", module ? "yes" : "no"); Py_XDECREF(module); Py_EndInterpreter(sub); } int main() { Py_InitializeEx(0); PyThreadState* interp = PyEval_SaveThread(); const char* module_name = "datetime"; sub_import(interp, module_name); sub_import(interp, module_name); // <- crash PyEval_AcquireThread(interp); Py_FinalizeEx(); } This is because the module will get loaded a second time, which will cause python to try and cleanup the old state from the old interpreter inside the new interpreter. // obmalloc.c void _PyObject_Free(void *ctx, void *p) // p will point to an object allocated by pymalloc from the old interpreter here { /* PyObject_Free(NULL) has no effect */ if (p == NULL) { return; } OMState *state = get_state(); if (UNLIKELY(!pymalloc_free(state, ctx, p))) { // <- this returns false, since the object does not belong to the new interpreter /* pymalloc didn't allocate this address */ PyMem_RawFree(p); // <- this will crash, since the pointer was not allocated directly through malloc raw_allocated_blocks--; } } This may be related to #117953 and #104621 but its important to note that this does not happen with the readline module as it correctly refuses to load. CPython versions tested on:3.12 Operating systems tested on:Linux Activity
MetadataMetadataAssigneesLabelstopic-subinterpreterstype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error Projects
MilestoneRelationshipsDevelopmentIssue actions |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |