From 5f55067e238c21de25f09ece9bb24ae8c42d02b4 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 16 Nov 2022 09:37:14 -0700 Subject: [PATCH] gh-81057: Move More Globals in Core Code to _PyRuntimeState (gh-99516) https://github.com/python/cpython/issues/81057 --- Include/cpython/modsupport.h | 2 - Include/internal/pycore_fileutils.h | 5 + Include/internal/pycore_floatobject.h | 12 ++ Include/internal/pycore_import.h | 2 + Include/internal/pycore_interp.h | 1 + Include/internal/pycore_pyhash.h | 32 +++- Include/internal/pycore_pylifecycle.h | 4 - Include/internal/pycore_runtime.h | 12 +- Include/internal/pycore_runtime_init.h | 34 +++-- Include/internal/pycore_unicodeobject.h | 4 + Modules/main.c | 6 +- Objects/floatobject.c | 27 ++-- Objects/moduleobject.c | 2 + Objects/unicodeobject.c | 19 ++- Python/bootstrap_hash.c | 10 +- Python/ceval_gil.c | 9 +- Python/fileutils.c | 2 +- Python/importdl.c | 2 + Python/modsupport.c | 3 - Python/pylifecycle.c | 2 - Python/pystate.c | 10 +- Python/pythonrun.c | 5 +- Tools/c-analyzer/cpython/globals-to-fix.tsv | 10 -- Tools/c-analyzer/cpython/ignored.tsv | 156 ++++++++++++-------- 24 files changed, 241 insertions(+), 130 deletions(-) diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h index d8458923b3f..88f34fe7513 100644 --- a/Include/cpython/modsupport.h +++ b/Include/cpython/modsupport.h @@ -106,5 +106,3 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( (minpos), (maxpos), (minkw), (buf))) PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver); - -PyAPI_DATA(const char *) _Py_PackageContext; diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index 3ce8108e4e0..ac89c43d569 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -10,6 +10,11 @@ extern "C" { #include /* struct lconv */ + +struct _fileutils_state { + int force_ascii; +}; + typedef enum { _Py_ERROR_UNKNOWN=0, _Py_ERROR_STRICT, diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h index 8a655543329..27c63bc87f3 100644 --- a/Include/internal/pycore_floatobject.h +++ b/Include/internal/pycore_floatobject.h @@ -19,6 +19,18 @@ extern void _PyFloat_FiniType(PyInterpreterState *); /* other API */ +enum _py_float_format_type { + _py_float_format_unknown, + _py_float_format_ieee_big_endian, + _py_float_format_ieee_little_endian, +}; + +struct _Py_float_runtime_state { + enum _py_float_format_type float_format; + enum _py_float_format_type double_format; +}; + + #ifndef WITH_FREELISTS // without freelists # define PyFloat_MAXFREELIST 0 diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 8ba9666cdcf..9036dff6725 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -32,6 +32,8 @@ struct _import_runtime_state { _PyTime_t accumulated; int header; } find_and_load; + /* Package context -- the full module name for package imports */ + const char * pkgcontext; }; diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index a13bc32e114..b7fc4b480d7 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -28,6 +28,7 @@ extern "C" { struct _pending_calls { + int busy; PyThread_type_lock lock; /* Request for running pending calls. */ _Py_atomic_int calls_to_do; diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h index a229f8d8b7f..34dfa537712 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -5,6 +5,36 @@ # error "this header requires Py_BUILD_CORE define" #endif + +struct pyhash_runtime_state { + struct { +#ifndef MS_WINDOWS + int fd; + dev_t st_dev; + ino_t st_ino; +#else + // This is a placeholder so the struct isn't empty on Windows. + int _not_used; +#endif + } urandom_cache; +}; + +#ifndef MS_WINDOWS +# define _py_urandom_cache_INIT \ + { \ + .fd = -1, \ + } +#else +# define _py_urandom_cache_INIT {0} +#endif + +#define pyhash_state_INIT \ + { \ + .urandom_cache = _py_urandom_cache_INIT, \ + } + + uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); -#endif + +#endif // Py_INTERNAL_HASH_H diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 359b809d587..4c0ffa7a9b1 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -14,10 +14,6 @@ extern "C" { struct _PyArgv; struct pyruntimestate; -/* True if the main interpreter thread exited due to an unhandled - * KeyboardInterrupt exception, suggesting the user pressed ^C. */ -PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; - extern int _Py_SetFileSystemEncoding( const char *encoding, const char *errors); diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index 8b2b9d7a85b..f8b988021b9 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -10,11 +10,13 @@ extern "C" { #include "pycore_atomic.h" /* _Py_atomic_address */ #include "pycore_dtoa.h" // struct _dtoa_runtime_state +#include "pycore_floatobject.h" // struct _Py_float_runtime_state #include "pycore_gil.h" // struct _gil_runtime_state #include "pycore_global_objects.h" // struct _Py_global_objects #include "pycore_import.h" // struct _import_runtime_state #include "pycore_interp.h" // PyInterpreterState #include "pycore_pymem.h" // struct _pymem_allocators +#include "pycore_pyhash.h" // struct pyhash_runtime_state #include "pycore_obmalloc.h" // struct obmalloc_state #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids @@ -92,6 +94,12 @@ typedef struct pyruntimestate { struct _pymem_allocators allocators; struct _obmalloc_state obmalloc; + struct pyhash_runtime_state pyhash_state; + struct { + /* True if the main interpreter thread exited due to an unhandled + * KeyboardInterrupt exception, suggesting the user pressed ^C. */ + int unhandled_keyboard_interrupt; + } signals; struct pyinterpreters { PyThread_type_lock mutex; @@ -131,6 +139,7 @@ typedef struct pyruntimestate { struct _PyTraceMalloc_Config config; } tracemalloc; struct _dtoa_runtime_state dtoa; + struct _fileutils_state fileutils; PyPreConfig preconfig; @@ -140,7 +149,8 @@ typedef struct pyruntimestate { void *open_code_userdata; _Py_AuditHookEntry *audit_hook_head; - struct _Py_unicode_runtime_ids unicode_ids; + struct _Py_float_runtime_state float_state; + struct _Py_unicode_runtime_state unicode_state; struct { /* Used to set PyTypeObject.tp_version_tag */ diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 6bdee36a851..37bc54ff96c 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -19,30 +19,18 @@ extern "C" { #define _PyRuntimeState_INIT(runtime) \ { \ - .gilstate = { \ - .check_enabled = 1, \ - /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ - in accordance with the specification. */ \ - .autoTSSkey = Py_tss_NEEDS_INIT, \ - }, \ .allocators = { \ _pymem_allocators_standard_INIT(runtime), \ _pymem_allocators_debug_INIT, \ _pymem_allocators_obj_arena_INIT, \ }, \ .obmalloc = _obmalloc_state_INIT(runtime.obmalloc), \ + .pyhash_state = pyhash_state_INIT, \ .interpreters = { \ /* This prevents interpreters from getting created \ until _PyInterpreterState_Enable() is called. */ \ .next_id = -1, \ }, \ - .tracemalloc = { \ - .config = _PyTraceMalloc_Config_INIT, \ - }, \ - .dtoa = _dtoa_runtime_state_INIT(runtime), \ - .types = { \ - .next_version_tag = 1, \ - }, \ .imports = { \ .lock = { \ .mutex = NULL, \ @@ -53,6 +41,26 @@ extern "C" { .header = 1, \ }, \ }, \ + .gilstate = { \ + .check_enabled = 1, \ + /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ + in accordance with the specification. */ \ + .autoTSSkey = Py_tss_NEEDS_INIT, \ + }, \ + .tracemalloc = { \ + .config = _PyTraceMalloc_Config_INIT, \ + }, \ + .dtoa = _dtoa_runtime_state_INIT(runtime), \ + .fileutils = { \ + .force_ascii = -1, \ + }, \ + .float_state = { \ + .float_format = _py_float_format_unknown, \ + .double_format = _py_float_format_unknown, \ + }, \ + .types = { \ + .next_version_tag = 1, \ + }, \ .global_objects = { \ .singletons = { \ .small_ints = _Py_small_ints_INIT, \ diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 63bf04b3e1b..b315ca1ae5b 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -31,6 +31,10 @@ struct _Py_unicode_runtime_ids { Py_ssize_t next_index; }; +struct _Py_unicode_runtime_state { + struct _Py_unicode_runtime_ids ids; +}; + /* fs_codec.encoding is initialized to NULL. Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ struct _Py_unicode_fs_codec { diff --git a/Modules/main.c b/Modules/main.c index aa523fc58d9..7edfeb3365b 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -296,10 +296,10 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(module); return pymain_exit_err_print(); } - _Py_UnhandledKeyboardInterrupt = 0; + _PyRuntime.signals.unhandled_keyboard_interrupt = 0; result = PyObject_Call(runmodule, runargs, NULL); if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; + _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } Py_DECREF(runpy); Py_DECREF(runmodule); @@ -696,7 +696,7 @@ Py_RunMain(void) pymain_free(); - if (_Py_UnhandledKeyboardInterrupt) { + if (_PyRuntime.signals.unhandled_keyboard_interrupt) { exitcode = exit_sigint(); } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 65383b2802c..46016e946ad 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1723,12 +1723,14 @@ float___getnewargs___impl(PyObject *self) } /* this is for the benefit of the pack/unpack routines below */ +typedef enum _py_float_format_type float_format_type; +#define unknown_format _py_float_format_unknown +#define ieee_big_endian_format _py_float_format_ieee_big_endian +#define ieee_little_endian_format _py_float_format_ieee_little_endian -typedef enum { - unknown_format, ieee_big_endian_format, ieee_little_endian_format -} float_format_type; +#define float_format (_PyRuntime.float_state.float_format) +#define double_format (_PyRuntime.float_state.double_format) -static float_format_type double_format, float_format; /*[clinic input] @classmethod @@ -1929,13 +1931,9 @@ PyTypeObject PyFloat_Type = { .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; -void -_PyFloat_InitState(PyInterpreterState *interp) +static void +_init_global_state(void) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - float_format_type detected_double_format, detected_float_format; /* We attempt to determine if this machine is using IEEE @@ -1985,6 +1983,15 @@ _PyFloat_InitState(PyInterpreterState *interp) float_format = detected_float_format; } +void +_PyFloat_InitState(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + _init_global_state(); +} + PyStatus _PyFloat_InitTypes(PyInterpreterState *interp) { diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 4a423a719e9..8e03f2446f6 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -218,6 +218,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version) _Py_PackageContext, and PyModule_Create*() will substitute this (if the name actually matches). */ +#define _Py_PackageContext (_PyRuntime.imports.pkgcontext) if (_Py_PackageContext != NULL) { const char *p = strrchr(_Py_PackageContext, '.'); if (p != NULL && strcmp(module->m_name, p+1) == 0) { @@ -225,6 +226,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version) _Py_PackageContext = NULL; } } +#undef _Py_PackageContext if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) return NULL; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index eaa8f581a75..b1acfc71379 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1856,7 +1856,7 @@ _PyUnicode_FromId(_Py_Identifier *id) Py_ssize_t index = _Py_atomic_size_get(&id->index); if (index < 0) { - struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids; + struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); // Check again to detect concurrent access. Another thread can have @@ -14491,12 +14491,14 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ -void -_PyUnicode_InitState(PyInterpreterState *interp) +static void +_init_global_state(void) { - if (!_Py_IsMainInterpreter(interp)) { + static int initialized = 0; + if (initialized) { return; } + initialized = 1; /* initialize the linebreak bloom filter */ const Py_UCS2 linebreak[] = { @@ -14514,6 +14516,15 @@ _PyUnicode_InitState(PyInterpreterState *interp) Py_ARRAY_LENGTH(linebreak)); } +void +_PyUnicode_InitState(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + _init_global_state(); +} + PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index 3a2a7318086..587063ef1ab 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -1,6 +1,7 @@ #include "Python.h" #include "pycore_initconfig.h" #include "pycore_fileutils.h" // _Py_fstat_noraise() +#include "pycore_runtime.h" // _PyRuntime #ifdef MS_WINDOWS # include @@ -263,11 +264,7 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise) #endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */ -static struct { - int fd; - dev_t st_dev; - ino_t st_ino; -} urandom_cache = { -1 }; +#define urandom_cache (_PyRuntime.pyhash_state.urandom_cache) /* Read random bytes from the /dev/urandom device: @@ -402,6 +399,9 @@ dev_urandom_close(void) urandom_cache.fd = -1; } } + +#undef urandom_cache + #endif /* !MS_WINDOWS */ diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index 9b9d7dc1d1a..83f4e91e545 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -819,11 +819,10 @@ make_pending_calls(PyInterpreterState *interp) } /* don't perform recursive pending calls */ - static int busy = 0; - if (busy) { + if (interp->ceval.pending.busy) { return 0; } - busy = 1; + interp->ceval.pending.busy = 1; /* unsignal before starting to call callbacks, so that any callback added in-between re-signals */ @@ -851,11 +850,11 @@ make_pending_calls(PyInterpreterState *interp) } } - busy = 0; + interp->ceval.pending.busy = 0; return res; error: - busy = 0; + interp->ceval.pending.busy = 0; SIGNAL_PENDING_CALLS(interp); return res; } diff --git a/Python/fileutils.c b/Python/fileutils.c index fb1e5ef9a03..244bd899b3b 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -191,7 +191,7 @@ extern int _Py_normalize_encoding(const char *, char *, size_t); Py_DecodeLocale() uses mbstowcs() -1: unknown, need to call check_force_ascii() to get the value */ -static int force_ascii = -1; +#define force_ascii (_PyRuntime.fileutils.force_ascii) static int check_force_ascii(void) diff --git a/Python/importdl.c b/Python/importdl.c index 870ae273007..40227674ca4 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -160,6 +160,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) p0 = (PyModInitFunction)exportfunc; /* Package context is needed for single-phase init */ +#define _Py_PackageContext (_PyRuntime.imports.pkgcontext) oldcontext = _Py_PackageContext; _Py_PackageContext = PyUnicode_AsUTF8(name_unicode); if (_Py_PackageContext == NULL) { @@ -168,6 +169,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) } m = _PyImport_InitFunc_TrampolineCall(p0); _Py_PackageContext = oldcontext; +#undef _Py_PackageContext if (m == NULL) { if (!PyErr_Occurred()) { diff --git a/Python/modsupport.c b/Python/modsupport.c index ee4bf14e63e..b9a10dc157e 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -10,9 +10,6 @@ typedef double va_double; static PyObject *va_build_value(const char *, va_list, int); static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); -/* Package context -- the full module name for package imports */ -const char *_Py_PackageContext = NULL; - int _Py_convert_optional_to_ssize_t(PyObject *obj, void *result) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7ca284ef1ef..10636b4d15d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -77,8 +77,6 @@ static PyStatus init_sys_streams(PyThreadState *tstate); static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); -int _Py_UnhandledKeyboardInterrupt = 0; - /* The following places the `_PyRuntime` structure in a location that can be * found without any external information. This is meant to ease access to the * interpreter state for various runtime debugging tools, but is *not* an diff --git a/Python/pystate.c b/Python/pystate.c index 5c9e4ff8553..b94fbf6ca0b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -137,8 +137,8 @@ init_runtime(_PyRuntimeState *runtime, // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); - runtime->unicode_ids.next_index = unicode_next_index; - runtime->unicode_ids.lock = unicode_ids_mutex; + runtime->unicode_state.ids.next_index = unicode_next_index; + runtime->unicode_state.ids.lock = unicode_ids_mutex; runtime->_initialized = 1; } @@ -154,7 +154,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; // bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize() // is called multiple times. - Py_ssize_t unicode_next_index = runtime->unicode_ids.next_index; + Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index; PyThread_type_lock lock1, lock2, lock3, lock4; if (alloc_for_runtime(&lock1, &lock2, &lock3, &lock4) != 0) { @@ -186,7 +186,7 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) FREE_LOCK(runtime->interpreters.mutex); FREE_LOCK(runtime->xidregistry.mutex); - FREE_LOCK(runtime->unicode_ids.lock); + FREE_LOCK(runtime->unicode_state.ids.lock); FREE_LOCK(runtime->getargs.mutex); #undef FREE_LOCK @@ -209,7 +209,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); - int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock); + int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_state.ids.lock); int reinit_getargs = _PyThread_at_fork_reinit(&runtime->getargs.mutex); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1c7ac4af63c..eead707b541 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1688,7 +1688,8 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py * uncaught exception to trigger an unexplained signal exit from a future * Py_Main() based one. */ - _Py_UnhandledKeyboardInterrupt = 0; + // XXX Isn't this dealt with by the move to _PyRuntimeState? + _PyRuntime.signals.unhandled_keyboard_interrupt = 0; /* Set globals['__builtins__'] if it doesn't exist */ if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) { @@ -1702,7 +1703,7 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py v = PyEval_EvalCode((PyObject*)co, globals, locals); if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; + _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } return v; } diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index b4ac9120d98..ee0c85bd425 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -336,17 +336,7 @@ Python/perf_trampoline.c - perf_status - Python/perf_trampoline.c - extra_code_index - Python/perf_trampoline.c - code_arena - Python/perf_trampoline.c - trampoline_api - -Parser/pegen.c - memo_statistics - -Python/bootstrap_hash.c - urandom_cache - -Python/ceval_gil.c make_pending_calls busy - -Python/ceval.c _PyEval_SetProfile reentrant - -Python/ceval.c _PyEval_SetTrace reentrant - -Python/modsupport.c - _Py_PackageContext - Python/thread_pthread_stubs.h - py_tls_entries - -Python/pyfpe.c - PyFPE_counter - -Python/pylifecycle.c _Py_FatalErrorFormat reentrant - -Python/pylifecycle.c - _Py_UnhandledKeyboardInterrupt - -Python/pylifecycle.c fatal_error reentrant - ################################## diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 0a6f3ec8152..242deace8c9 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -1,16 +1,95 @@ filename funcname name reason #??? - somevar ??? +# All globals here are technically mutable but known to be safe. + + ################################## -# mutable but known to be safe +# process-global resources + +# Initialization for these should be idempotent. + +#----------------------- +# effectively const, set once before/during first init + +Modules/getbuildinfo.c - buildinfo - +Modules/getbuildinfo.c - initialized - +Python/getversion.c - initialized - +Python/getversion.c - version - + +#----------------------- +# effectively const, set once during first init + +Python/bootstrap_hash.c - _Py_HashSecret_Initialized - +Python/pyhash.c - _Py_HashSecret - +Python/thread.c - initialized - +Python/thread_pthread.h - condattr_monotonic - + +# safe static buffer used during one-time initialization +Python/thread_pthread.h init_condattr ca - + +# indicators for process-global resource availability/capability +Python/bootstrap_hash.c py_getrandom getrandom_works - +Python/fileutils.c - _Py_open_cloexec_works - +Python/fileutils.c set_inheritable ioctl_works - + +#----------------------- +# effectively const but set once lazily (*after* first init) + +Objects/longobject.c long_from_non_binary_base log_base_BASE - +Objects/longobject.c long_from_non_binary_base convwidth_base - +Objects/longobject.c long_from_non_binary_base convmultmax_base - +Objects/unicodeobject.c - bloom_linebreak - +Objects/unicodeobject.c _init_global_state initialized - + +# XXX Move to _PyRuntimeState? +Parser/action_helpers.c _PyPegen_dummy_name cache - + + +################################## +# state tied to C main() (only in main thread) + +#----------------------- +# handling C argv + +Python/getopt.c - _PyOS_optarg - +Python/getopt.c - _PyOS_opterr - +Python/getopt.c - _PyOS_optind - +Python/getopt.c - opt_ptr - +Python/pathconfig.c - _Py_path_config - + +#----------------------- +# REPL + +Parser/myreadline.c - _PyOS_ReadlineLock - +Parser/myreadline.c - _PyOS_ReadlineTState - +Parser/myreadline.c - PyOS_InputHook - +Parser/myreadline.c - PyOS_ReadlineFunctionPointer - + + +################################## +# state tied to each runtime init/fini cycle Python/pylifecycle.c - _PyRuntime - +Python/pylifecycle.c - runtime_initialized - # All uses of _PyArg_Parser are handled in c-analyzr/cpython/_analyzer.py. #----------------------- -# legacy config flags +# effectively const once init finishes +# set by embedders before init (whether directly or through a call) +Python/initconfig.c - _Py_StandardStreamEncoding - +Python/initconfig.c - _Py_StandardStreamErrors - +Python/initconfig.c - orig_argv - + +# deprecated +Python/preconfig.c - Py_FileSystemDefaultEncoding - +Python/preconfig.c - Py_HasFileSystemDefaultEncoding - +Python/preconfig.c - Py_FileSystemDefaultEncodeErrors - +Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors - + +# legacy config flags Python/initconfig.c - Py_UTF8Mode - Python/initconfig.c - Py_DebugFlag - Python/initconfig.c - Py_VerboseFlag - @@ -30,75 +109,34 @@ Python/initconfig.c - Py_IsolatedFlag - Python/initconfig.c - Py_LegacyWindowsFSEncodingFlag - Python/initconfig.c - Py_LegacyWindowsStdioFlag - -#----------------------- -# effectively const, initialized before init - +# initialized statically, customized by embedders Python/frozen.c - PyImport_FrozenModules - Python/import.c - inittab_copy - Python/import.c - PyImport_Inittab - -#----------------------- -# effectively const, initialized before/during init - -Modules/getbuildinfo.c - buildinfo - -Modules/getbuildinfo.c - initialized - -Python/getversion.c - initialized - -Python/getversion.c - version - - -#----------------------- -# effectively const, initialized during init - -Objects/floatobject.c - double_format - -Objects/floatobject.c - float_format - -Objects/unicodeobject.c - bloom_linebreak - -Python/bootstrap_hash.c py_getrandom getrandom_works - -Python/bootstrap_hash.c - _Py_HashSecret_Initialized - -Python/fileutils.c - _Py_open_cloexec_works - -Python/fileutils.c - force_ascii - -Python/fileutils.c set_inheritable ioctl_works - -Python/import.c import_find_and_load header - -Python/initconfig.c - orig_argv - -Python/preconfig.c - Py_FileSystemDefaultEncoding - -Python/preconfig.c - Py_HasFileSystemDefaultEncoding - -Python/preconfig.c - Py_FileSystemDefaultEncodeErrors - -Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors - -Python/pyhash.c - _Py_HashSecret - -Python/pylifecycle.c - runtime_initialized - +# used temporarily during init Python/sysmodule.c - _preinit_warnoptions - Python/sysmodule.c - _preinit_xoptions - -Python/thread.c - initialized - -Python/thread_pthread.h - condattr_monotonic - -Python/thread_pthread.h init_condattr ca - -# set by embedders during init -Python/initconfig.c - _Py_StandardStreamEncoding - -Python/initconfig.c - _Py_StandardStreamErrors - -#----------------------- -# effectively const but initialized lazily -# XXX Move them to _PyRuntimeState? +################################## +# special-use diagnistic state -# idempotent -Objects/longobject.c long_from_non_binary_base log_base_BASE - -Objects/longobject.c long_from_non_binary_base convwidth_base - -Objects/longobject.c long_from_non_binary_base convmultmax_base - -Parser/action_helpers.c _PyPegen_dummy_name cache - +Parser/pegen.c - memo_statistics - -#----------------------- -# used only in the main thread -# REPL -Parser/myreadline.c - _PyOS_ReadlineLock - -Parser/myreadline.c - _PyOS_ReadlineTState - -Parser/myreadline.c - PyOS_InputHook - -Parser/myreadline.c - PyOS_ReadlineFunctionPointer - +################################## +# one-off temporary state -# handling C argv -Python/getopt.c - _PyOS_optarg - -Python/getopt.c - _PyOS_opterr - -Python/getopt.c - _PyOS_optind - -Python/getopt.c - opt_ptr - -Python/pathconfig.c - _Py_path_config - +# This is safe enough. +Python/pylifecycle.c _Py_FatalErrorFormat reentrant - +Python/pylifecycle.c fatal_error reentrant - + + +################################## +# not used (kept for compatibility) + +Python/pyfpe.c - PyFPE_counter - ##################################