LCOV - code coverage report
Current view: | top level - Python - pylifecycle.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 600 | 1155 | 51.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 48 | 79 | 60.8 %
|  |  | Branches: | 234 | 670 | 34.9 %

               Branch data     Line data    Source code
           1                 :            : /* Python interpreter top-level routines, including init/exit */
           2                 :            :
           3                 :            : #include "Python.h"
           4                 :            :
           5                 :            : #include "pycore_bytesobject.h"   // _PyBytes_InitTypes()
           6                 :            : #include "pycore_ceval.h"         // _PyEval_FiniGIL()
           7                 :            : #include "pycore_context.h"       // _PyContext_Init()
           8                 :            : #include "pycore_exceptions.h"    // _PyExc_InitTypes()
           9                 :            : #include "pycore_dict.h"          // _PyDict_Fini()
          10                 :            : #include "pycore_fileutils.h"     // _Py_ResetForceASCII()
          11                 :            : #include "pycore_floatobject.h"   // _PyFloat_InitTypes()
          12                 :            : #include "pycore_genobject.h"     // _PyAsyncGen_Fini()
          13                 :            : #include "pycore_global_objects_fini_generated.h"  // "_PyStaticObjects_CheckRefcnt()
          14                 :            : #include "pycore_import.h"        // _PyImport_BootstrapImp()
          15                 :            : #include "pycore_initconfig.h"    // _PyStatus_OK()
          16                 :            : #include "pycore_list.h"          // _PyList_Fini()
          17                 :            : #include "pycore_long.h"          // _PyLong_InitTypes()
          18                 :            : #include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
          19                 :            : #include "pycore_pathconfig.h"    // _PyConfig_WritePathConfig()
          20                 :            : #include "pycore_pyerrors.h"      // _PyErr_Occurred()
          21                 :            : #include "pycore_pylifecycle.h"   // _PyErr_Print()
          22                 :            : #include "pycore_pymem.h"         // _PyObject_DebugMallocStats()
          23                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
          24                 :            : #include "pycore_runtime.h"       // _Py_ID()
          25                 :            : #include "pycore_runtime_init.h"  // _PyRuntimeState_INIT
          26                 :            : #include "pycore_sliceobject.h"   // _PySlice_Fini()
          27                 :            : #include "pycore_sysmodule.h"     // _PySys_ClearAuditHooks()
          28                 :            : #include "pycore_traceback.h"     // _Py_DumpTracebackThreads()
          29                 :            : #include "pycore_tuple.h"         // _PyTuple_InitTypes()
          30                 :            : #include "pycore_typeobject.h"    // _PyTypes_InitTypes()
          31                 :            : #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
          32                 :            : #include "opcode.h"
          33                 :            :
          34                 :            : extern void _PyIO_Fini(void);
          35                 :            :
          36                 :            : #include <locale.h>               // setlocale()
          37                 :            : #include <stdlib.h>               // getenv()
          38                 :            :
          39                 :            : #if defined(__APPLE__)
          40                 :            : #include <mach-o/loader.h>
          41                 :            : #endif
          42                 :            :
          43                 :            : #ifdef HAVE_SIGNAL_H
          44                 :            : #  include <signal.h>             // SIG_IGN
          45                 :            : #endif
          46                 :            :
          47                 :            : #ifdef HAVE_LANGINFO_H
          48                 :            : #  include <langinfo.h>           // nl_langinfo(CODESET)
          49                 :            : #endif
          50                 :            :
          51                 :            : #ifdef HAVE_FCNTL_H
          52                 :            : #  include <fcntl.h>              // F_GETFD
          53                 :            : #endif
          54                 :            :
          55                 :            : #ifdef MS_WINDOWS
          56                 :            : #  undef BYTE
          57                 :            : #endif
          58                 :            :
          59                 :            : #define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
          60                 :            :
          61                 :            :
          62                 :            : #ifdef __cplusplus
          63                 :            : extern "C" {
          64                 :            : #endif
          65                 :            :
          66                 :            :
          67                 :            : /* Forward declarations */
          68                 :            : static PyStatus add_main_module(PyInterpreterState *interp);
          69                 :            : static PyStatus init_import_site(void);
          70                 :            : static PyStatus init_set_builtins_open(void);
          71                 :            : static PyStatus init_sys_streams(PyThreadState *tstate);
          72                 :            : static void wait_for_thread_shutdown(PyThreadState *tstate);
          73                 :            : static void call_ll_exitfuncs(_PyRuntimeState *runtime);
          74                 :            :
          75                 :            : /* The following places the `_PyRuntime` structure in a location that can be
          76                 :            :  * found without any external information. This is meant to ease access to the
          77                 :            :  * interpreter state for various runtime debugging tools, but is *not* an
          78                 :            :  * officially supported feature */
          79                 :            :
          80                 :            : /* Suppress deprecation warning for PyBytesObject.ob_shash */
          81                 :            : _Py_COMP_DIAG_PUSH
          82                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
          83                 :            :
          84                 :            : #if defined(MS_WINDOWS)
          85                 :            :
          86                 :            : #pragma section("PyRuntime", read, write)
          87                 :            : __declspec(allocate("PyRuntime"))
          88                 :            :
          89                 :            : #elif defined(__APPLE__)
          90                 :            :
          91                 :            : __attribute__((
          92                 :            :     section(SEG_DATA ",PyRuntime")
          93                 :            : ))
          94                 :            :
          95                 :            : #endif
          96                 :            :
          97                 :            : _PyRuntimeState _PyRuntime
          98                 :            : #if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
          99                 :            : __attribute__ ((section (".PyRuntime")))
         100                 :            : #endif
         101                 :            : = _PyRuntimeState_INIT(_PyRuntime);
         102                 :            : _Py_COMP_DIAG_POP
         103                 :            :
         104                 :            : static int runtime_initialized = 0;
         105                 :            :
         106                 :            : PyStatus
         107                 :       2004 : _PyRuntime_Initialize(void)
         108                 :            : {
         109                 :            :     /* XXX We only initialize once in the process, which aligns with
         110                 :            :        the static initialization of the former globals now found in
         111                 :            :        _PyRuntime.  However, _PyRuntime *should* be initialized with
         112                 :            :        every Py_Initialize() call, but doing so breaks the runtime.
         113                 :            :        This is because the runtime state is not properly finalized
         114                 :            :        currently. */
         115         [ +  + ]:       2004 :     if (runtime_initialized) {
         116                 :       1975 :         return _PyStatus_OK();
         117                 :            :     }
         118                 :         29 :     runtime_initialized = 1;
         119                 :            :
         120                 :         29 :     return _PyRuntimeState_Init(&_PyRuntime);
         121                 :            : }
         122                 :            :
         123                 :            : void
         124                 :         50 : _PyRuntime_Finalize(void)
         125                 :            : {
         126                 :         50 :     _PyRuntimeState_Fini(&_PyRuntime);
         127                 :         50 :     runtime_initialized = 0;
         128                 :         50 : }
         129                 :            :
         130                 :            : int
         131                 :          0 : _Py_IsFinalizing(void)
         132                 :            : {
         133                 :          0 :     return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL;
         134                 :            : }
         135                 :            :
         136                 :            : /* Hack to force loading of object files */
         137                 :            : int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \
         138                 :            :     PyOS_mystrnicmp; /* Python/pystrcmp.o */
         139                 :            :
         140                 :            :
         141                 :            : /* APIs to access the initialization flags
         142                 :            :  *
         143                 :            :  * Can be called prior to Py_Initialize.
         144                 :            :  */
         145                 :            :
         146                 :            : int
         147                 :          0 : _Py_IsCoreInitialized(void)
         148                 :            : {
         149                 :          0 :     return _PyRuntime.core_initialized;
         150                 :            : }
         151                 :            :
         152                 :            : int
         153                 :          0 : Py_IsInitialized(void)
         154                 :            : {
         155                 :          0 :     return _PyRuntime.initialized;
         156                 :            : }
         157                 :            :
         158                 :            :
         159                 :            : /* Helper functions to better handle the legacy C locale
         160                 :            :  *
         161                 :            :  * The legacy C locale assumes ASCII as the default text encoding, which
         162                 :            :  * causes problems not only for the CPython runtime, but also other
         163                 :            :  * components like GNU readline.
         164                 :            :  *
         165                 :            :  * Accordingly, when the CLI detects it, it attempts to coerce it to a
         166                 :            :  * more capable UTF-8 based alternative as follows:
         167                 :            :  *
         168                 :            :  *     if (_Py_LegacyLocaleDetected()) {
         169                 :            :  *         _Py_CoerceLegacyLocale();
         170                 :            :  *     }
         171                 :            :  *
         172                 :            :  * See the documentation of the PYTHONCOERCECLOCALE setting for more details.
         173                 :            :  *
         174                 :            :  * Locale coercion also impacts the default error handler for the standard
         175                 :            :  * streams: while the usual default is "strict", the default for the legacy
         176                 :            :  * C locale and for any of the coercion target locales is "surrogateescape".
         177                 :            :  */
         178                 :            :
         179                 :            : int
         180                 :          4 : _Py_LegacyLocaleDetected(int warn)
         181                 :            : {
         182                 :            : #ifndef MS_WINDOWS
         183         [ +  - ]:          4 :     if (!warn) {
         184                 :          4 :         const char *locale_override = getenv("LC_ALL");
         185   [ -  +  -  - ]:          4 :         if (locale_override != NULL && *locale_override != '\0') {
         186                 :            :             /* Don't coerce C locale if the LC_ALL environment variable
         187                 :            :                is set */
         188                 :          0 :             return 0;
         189                 :            :         }
         190                 :            :     }
         191                 :            :
         192                 :            :     /* On non-Windows systems, the C locale is considered a legacy locale */
         193                 :            :     /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat
         194                 :            :      *                 the POSIX locale as a simple alias for the C locale, so
         195                 :            :      *                 we may also want to check for that explicitly.
         196                 :            :      */
         197                 :          4 :     const char *ctype_loc = setlocale(LC_CTYPE, NULL);
         198   [ +  -  -  + ]:          4 :     return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0;
         199                 :            : #else
         200                 :            :     /* Windows uses code pages instead of locales, so no locale is legacy */
         201                 :            :     return 0;
         202                 :            : #endif
         203                 :            : }
         204                 :            :
         205                 :            : #ifndef MS_WINDOWS
         206                 :            : static const char *_C_LOCALE_WARNING =
         207                 :            :     "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII "
         208                 :            :     "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, "
         209                 :            :     "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible "
         210                 :            :     "locales is recommended.\n";
         211                 :            :
         212                 :            : static void
         213                 :         25 : emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
         214                 :            : {
         215                 :         25 :     const PyPreConfig *preconfig = &runtime->preconfig;
         216   [ -  +  -  - ]:         25 :     if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) {
         217                 :          0 :         PySys_FormatStderr("%s", _C_LOCALE_WARNING);
         218                 :            :     }
         219                 :         25 : }
         220                 :            : #endif   /* !defined(MS_WINDOWS) */
         221                 :            :
         222                 :            : typedef struct _CandidateLocale {
         223                 :            :     const char *locale_name; /* The locale to try as a coercion target */
         224                 :            : } _LocaleCoercionTarget;
         225                 :            :
         226                 :            : static _LocaleCoercionTarget _TARGET_LOCALES[] = {
         227                 :            :     {"C.UTF-8"},
         228                 :            :     {"C.utf8"},
         229                 :            :     {"UTF-8"},
         230                 :            :     {NULL}
         231                 :            : };
         232                 :            :
         233                 :            :
         234                 :            : int
         235                 :          4 : _Py_IsLocaleCoercionTarget(const char *ctype_loc)
         236                 :            : {
         237                 :          4 :     const _LocaleCoercionTarget *target = NULL;
         238         [ +  + ]:         16 :     for (target = _TARGET_LOCALES; target->locale_name; target++) {
         239         [ -  + ]:         12 :         if (strcmp(ctype_loc, target->locale_name) == 0) {
         240                 :          0 :             return 1;
         241                 :            :         }
         242                 :            :     }
         243                 :          4 :     return 0;
         244                 :            : }
         245                 :            :
         246                 :            :
         247                 :            : #ifdef PY_COERCE_C_LOCALE
         248                 :            : static const char C_LOCALE_COERCION_WARNING[] =
         249                 :            :     "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale "
         250                 :            :     "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n";
         251                 :            :
         252                 :            : static int
         253                 :          0 : _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
         254                 :            : {
         255                 :          0 :     const char *newloc = target->locale_name;
         256                 :            :
         257                 :            :     /* Reset locale back to currently configured defaults */
         258                 :          0 :     _Py_SetLocaleFromEnv(LC_ALL);
         259                 :            :
         260                 :            :     /* Set the relevant locale environment variable */
         261         [ #  # ]:          0 :     if (setenv("LC_CTYPE", newloc, 1)) {
         262                 :          0 :         fprintf(stderr,
         263                 :            :                 "Error setting LC_CTYPE, skipping C locale coercion\n");
         264                 :          0 :         return 0;
         265                 :            :     }
         266         [ #  # ]:          0 :     if (warn) {
         267                 :          0 :         fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc);
         268                 :            :     }
         269                 :            :
         270                 :            :     /* Reconfigure with the overridden environment variables */
         271                 :          0 :     _Py_SetLocaleFromEnv(LC_ALL);
         272                 :          0 :     return 1;
         273                 :            : }
         274                 :            : #endif
         275                 :            :
         276                 :            : int
         277                 :          0 : _Py_CoerceLegacyLocale(int warn)
         278                 :            : {
         279                 :          0 :     int coerced = 0;
         280                 :            : #ifdef PY_COERCE_C_LOCALE
         281                 :          0 :     char *oldloc = NULL;
         282                 :            :
         283                 :          0 :     oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL));
         284         [ #  # ]:          0 :     if (oldloc == NULL) {
         285                 :          0 :         return coerced;
         286                 :            :     }
         287                 :            :
         288                 :          0 :     const char *locale_override = getenv("LC_ALL");
         289   [ #  #  #  # ]:          0 :     if (locale_override == NULL || *locale_override == '\0') {
         290                 :            :         /* LC_ALL is also not set (or is set to an empty string) */
         291                 :          0 :         const _LocaleCoercionTarget *target = NULL;
         292         [ #  # ]:          0 :         for (target = _TARGET_LOCALES; target->locale_name; target++) {
         293                 :          0 :             const char *new_locale = setlocale(LC_CTYPE,
         294                 :            :                                                target->locale_name);
         295         [ #  # ]:          0 :             if (new_locale != NULL) {
         296                 :            : #if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
         297                 :            :                 /* Also ensure that nl_langinfo works in this locale */
         298                 :          0 :                 char *codeset = nl_langinfo(CODESET);
         299   [ #  #  #  # ]:          0 :                 if (!codeset || *codeset == '\0') {
         300                 :            :                     /* CODESET is not set or empty, so skip coercion */
         301                 :          0 :                     new_locale = NULL;
         302                 :          0 :                     _Py_SetLocaleFromEnv(LC_CTYPE);
         303                 :          0 :                     continue;
         304                 :            :                 }
         305                 :            : #endif
         306                 :            :                 /* Successfully configured locale, so make it the default */
         307                 :          0 :                 coerced = _coerce_default_locale_settings(warn, target);
         308                 :          0 :                 goto done;
         309                 :            :             }
         310                 :            :         }
         311                 :            :     }
         312                 :            :     /* No C locale warning here, as Py_Initialize will emit one later */
         313                 :            :
         314                 :          0 :     setlocale(LC_CTYPE, oldloc);
         315                 :            :
         316                 :          0 : done:
         317                 :          0 :     PyMem_RawFree(oldloc);
         318                 :            : #endif
         319                 :          0 :     return coerced;
         320                 :            : }
         321                 :            :
         322                 :            : /* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to
         323                 :            :  * isolate the idiosyncrasies of different libc implementations. It reads the
         324                 :            :  * appropriate environment variable and uses its value to select the locale for
         325                 :            :  * 'category'. */
         326                 :            : char *
         327                 :          8 : _Py_SetLocaleFromEnv(int category)
         328                 :            : {
         329                 :            :     char *res;
         330                 :            : #ifdef __ANDROID__
         331                 :            :     const char *locale;
         332                 :            :     const char **pvar;
         333                 :            : #ifdef PY_COERCE_C_LOCALE
         334                 :            :     const char *coerce_c_locale;
         335                 :            : #endif
         336                 :            :     const char *utf8_locale = "C.UTF-8";
         337                 :            :     const char *env_var_set[] = {
         338                 :            :         "LC_ALL",
         339                 :            :         "LC_CTYPE",
         340                 :            :         "LANG",
         341                 :            :         NULL,
         342                 :            :     };
         343                 :            :
         344                 :            :     /* Android setlocale(category, "") doesn't check the environment variables
         345                 :            :      * and incorrectly sets the "C" locale at API 24 and older APIs. We only
         346                 :            :      * check the environment variables listed in env_var_set. */
         347                 :            :     for (pvar=env_var_set; *pvar; pvar++) {
         348                 :            :         locale = getenv(*pvar);
         349                 :            :         if (locale != NULL && *locale != '\0') {
         350                 :            :             if (strcmp(locale, utf8_locale) == 0 ||
         351                 :            :                     strcmp(locale, "en_US.UTF-8") == 0) {
         352                 :            :                 return setlocale(category, utf8_locale);
         353                 :            :             }
         354                 :            :             return setlocale(category, "C");
         355                 :            :         }
         356                 :            :     }
         357                 :            :
         358                 :            :     /* Android uses UTF-8, so explicitly set the locale to C.UTF-8 if none of
         359                 :            :      * LC_ALL, LC_CTYPE, or LANG is set to a non-empty string.
         360                 :            :      * Quote from POSIX section "8.2 Internationalization Variables":
         361                 :            :      * "4. If the LANG environment variable is not set or is set to the empty
         362                 :            :      * string, the implementation-defined default locale shall be used." */
         363                 :            :
         364                 :            : #ifdef PY_COERCE_C_LOCALE
         365                 :            :     coerce_c_locale = getenv("PYTHONCOERCECLOCALE");
         366                 :            :     if (coerce_c_locale == NULL || strcmp(coerce_c_locale, "0") != 0) {
         367                 :            :         /* Some other ported code may check the environment variables (e.g. in
         368                 :            :          * extension modules), so we make sure that they match the locale
         369                 :            :          * configuration */
         370                 :            :         if (setenv("LC_CTYPE", utf8_locale, 1)) {
         371                 :            :             fprintf(stderr, "Warning: failed setting the LC_CTYPE "
         372                 :            :                             "environment variable to %s\n", utf8_locale);
         373                 :            :         }
         374                 :            :     }
         375                 :            : #endif
         376                 :            :     res = setlocale(category, utf8_locale);
         377                 :            : #else /* !defined(__ANDROID__) */
         378                 :          8 :     res = setlocale(category, "");
         379                 :            : #endif
         380                 :          8 :     _Py_ResetForceASCII();
         381                 :          8 :     return res;
         382                 :            : }
         383                 :            :
         384                 :            :
         385                 :            : static int
         386                 :         25 : interpreter_update_config(PyThreadState *tstate, int only_update_path_config)
         387                 :            : {
         388                 :         25 :     const PyConfig *config = &tstate->interp->config;
         389                 :            :
         390         [ -  + ]:         25 :     if (!only_update_path_config) {
         391                 :          0 :         PyStatus status = _PyConfig_Write(config, tstate->interp->runtime);
         392         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
         393                 :          0 :             _PyErr_SetFromPyStatus(status);
         394                 :          0 :             return -1;
         395                 :            :         }
         396                 :            :     }
         397                 :            :
         398         [ +  - ]:         25 :     if (_Py_IsMainInterpreter(tstate->interp)) {
         399                 :         25 :         PyStatus status = _PyPathConfig_UpdateGlobal(config);
         400         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
         401                 :          0 :             _PyErr_SetFromPyStatus(status);
         402                 :          0 :             return -1;
         403                 :            :         }
         404                 :            :     }
         405                 :            :
         406                 :         25 :     tstate->interp->long_state.max_str_digits = config->int_max_str_digits;
         407                 :            :
         408                 :            :     // Update the sys module for the new configuration
         409         [ -  + ]:         25 :     if (_PySys_UpdateConfig(tstate) < 0) {
         410                 :          0 :         return -1;
         411                 :            :     }
         412                 :         25 :     return 0;
         413                 :            : }
         414                 :            :
         415                 :            :
         416                 :            : int
         417                 :          0 : _PyInterpreterState_SetConfig(const PyConfig *src_config)
         418                 :            : {
         419                 :          0 :     PyThreadState *tstate = _PyThreadState_GET();
         420                 :          0 :     int res = -1;
         421                 :            :
         422                 :            :     PyConfig config;
         423                 :          0 :     PyConfig_InitPythonConfig(&config);
         424                 :          0 :     PyStatus status = _PyConfig_Copy(&config, src_config);
         425         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
         426                 :          0 :         _PyErr_SetFromPyStatus(status);
         427                 :          0 :         goto done;
         428                 :            :     }
         429                 :            :
         430                 :          0 :     status = _PyConfig_Read(&config, 1);
         431         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
         432                 :          0 :         _PyErr_SetFromPyStatus(status);
         433                 :          0 :         goto done;
         434                 :            :     }
         435                 :            :
         436                 :          0 :     status = _PyConfig_Copy(&tstate->interp->config, &config);
         437         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
         438                 :          0 :         _PyErr_SetFromPyStatus(status);
         439                 :          0 :         goto done;
         440                 :            :     }
         441                 :            :
         442                 :          0 :     res = interpreter_update_config(tstate, 0);
         443                 :            :
         444                 :          0 : done:
         445                 :          0 :     PyConfig_Clear(&config);
         446                 :          0 :     return res;
         447                 :            : }
         448                 :            :
         449                 :            :
         450                 :            : /* Global initializations.  Can be undone by Py_Finalize().  Don't
         451                 :            :    call this twice without an intervening Py_Finalize() call.
         452                 :            :
         453                 :            :    Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx
         454                 :            :    must have a corresponding call to Py_Finalize.
         455                 :            :
         456                 :            :    Locking: you must hold the interpreter lock while calling these APIs.
         457                 :            :    (If the lock has not yet been initialized, that's equivalent to
         458                 :            :    having the lock, but you cannot use multiple threads.)
         459                 :            :
         460                 :            : */
         461                 :            :
         462                 :            : static PyStatus
         463                 :          0 : pyinit_core_reconfigure(_PyRuntimeState *runtime,
         464                 :            :                         PyThreadState **tstate_p,
         465                 :            :                         const PyConfig *config)
         466                 :            : {
         467                 :            :     PyStatus status;
         468                 :          0 :     PyThreadState *tstate = _PyThreadState_GET();
         469         [ #  # ]:          0 :     if (!tstate) {
         470                 :          0 :         return _PyStatus_ERR("failed to read thread state");
         471                 :            :     }
         472                 :          0 :     *tstate_p = tstate;
         473                 :            :
         474                 :          0 :     PyInterpreterState *interp = tstate->interp;
         475         [ #  # ]:          0 :     if (interp == NULL) {
         476                 :          0 :         return _PyStatus_ERR("can't make main interpreter");
         477                 :            :     }
         478                 :            :
         479                 :          0 :     status = _PyConfig_Write(config, runtime);
         480         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
         481                 :          0 :         return status;
         482                 :            :     }
         483                 :            :
         484                 :          0 :     status = _PyConfig_Copy(&interp->config, config);
         485         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
         486                 :          0 :         return status;
         487                 :            :     }
         488                 :          0 :     config = _PyInterpreterState_GetConfig(interp);
         489                 :            :
         490         [ #  # ]:          0 :     if (config->_install_importlib) {
         491                 :          0 :         status = _PyPathConfig_UpdateGlobal(config);
         492         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
         493                 :          0 :             return status;
         494                 :            :         }
         495                 :            :     }
         496                 :          0 :     return _PyStatus_OK();
         497                 :            : }
         498                 :            :
         499                 :            :
         500                 :            : static PyStatus
         501                 :         29 : pycore_init_runtime(_PyRuntimeState *runtime,
         502                 :            :                     const PyConfig *config)
         503                 :            : {
         504         [ -  + ]:         29 :     if (runtime->initialized) {
         505                 :          0 :         return _PyStatus_ERR("main interpreter already initialized");
         506                 :            :     }
         507                 :            :
         508                 :         29 :     PyStatus status = _PyConfig_Write(config, runtime);
         509         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         510                 :          0 :         return status;
         511                 :            :     }
         512                 :            :
         513                 :            :     /* Py_Finalize leaves _Py_Finalizing set in order to help daemon
         514                 :            :      * threads behave a little more gracefully at interpreter shutdown.
         515                 :            :      * We clobber it here so the new interpreter can start with a clean
         516                 :            :      * slate.
         517                 :            :      *
         518                 :            :      * However, this may still lead to misbehaviour if there are daemon
         519                 :            :      * threads still hanging around from a previous Py_Initialize/Finalize
         520                 :            :      * pair :(
         521                 :            :      */
         522                 :         29 :     _PyRuntimeState_SetFinalizing(runtime, NULL);
         523                 :            :
         524                 :         29 :     _Py_InitVersion();
         525                 :            :
         526                 :         29 :     status = _Py_HashRandomization_Init(config);
         527         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         528                 :          0 :         return status;
         529                 :            :     }
         530                 :            :
         531                 :         29 :     status = _PyTime_Init();
         532         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         533                 :          0 :         return status;
         534                 :            :     }
         535                 :            :
         536                 :         29 :     status = _PyImport_Init();
         537         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         538                 :          0 :         return status;
         539                 :            :     }
         540                 :            :
         541                 :         29 :     status = _PyInterpreterState_Enable(runtime);
         542         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         543                 :          0 :         return status;
         544                 :            :     }
         545                 :         29 :     return _PyStatus_OK();
         546                 :            : }
         547                 :            :
         548                 :            :
         549                 :            : static void
         550                 :         29 : init_interp_settings(PyInterpreterState *interp, const _PyInterpreterConfig *config)
         551                 :            : {
         552                 :            :     assert(interp->feature_flags == 0);
         553                 :            :
         554         [ +  - ]:         29 :     if (config->allow_fork) {
         555                 :         29 :         interp->feature_flags |= Py_RTFLAGS_FORK;
         556                 :            :     }
         557         [ +  - ]:         29 :     if (config->allow_exec) {
         558                 :         29 :         interp->feature_flags |= Py_RTFLAGS_EXEC;
         559                 :            :     }
         560                 :            :     // Note that fork+exec is always allowed.
         561                 :            :
         562         [ +  - ]:         29 :     if (config->allow_threads) {
         563                 :         29 :         interp->feature_flags |= Py_RTFLAGS_THREADS;
         564                 :            :     }
         565         [ +  - ]:         29 :     if (config->allow_daemon_threads) {
         566                 :         29 :         interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS;
         567                 :            :     }
         568                 :            :
         569         [ -  + ]:         29 :     if (config->check_multi_interp_extensions) {
         570                 :          0 :         interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
         571                 :            :     }
         572                 :         29 : }
         573                 :            :
         574                 :            :
         575                 :            : static PyStatus
         576                 :         29 : init_interp_create_gil(PyThreadState *tstate)
         577                 :            : {
         578                 :            :     PyStatus status;
         579                 :            :
         580                 :            :     /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is
         581                 :            :        only called here. */
         582                 :         29 :     _PyEval_FiniGIL(tstate->interp);
         583                 :            :
         584                 :            :     /* Auto-thread-state API */
         585                 :         29 :     status = _PyGILState_SetTstate(tstate);
         586         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         587                 :          0 :         return status;
         588                 :            :     }
         589                 :            :
         590                 :            :     /* Create the GIL and take it */
         591                 :         29 :     status = _PyEval_InitGIL(tstate);
         592         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         593                 :          0 :         return status;
         594                 :            :     }
         595                 :            :
         596                 :         29 :     return _PyStatus_OK();
         597                 :            : }
         598                 :            :
         599                 :            :
         600                 :            : static PyStatus
         601                 :         29 : pycore_create_interpreter(_PyRuntimeState *runtime,
         602                 :            :                           const PyConfig *src_config,
         603                 :            :                           PyThreadState **tstate_p)
         604                 :            : {
         605                 :            :     PyStatus status;
         606                 :         29 :     PyInterpreterState *interp = PyInterpreterState_New();
         607         [ -  + ]:         29 :     if (interp == NULL) {
         608                 :          0 :         return _PyStatus_ERR("can't make main interpreter");
         609                 :            :     }
         610                 :            :     assert(_Py_IsMainInterpreter(interp));
         611                 :            :
         612                 :         29 :     status = _PyConfig_Copy(&interp->config, src_config);
         613         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         614                 :          0 :         return status;
         615                 :            :     }
         616                 :            :
         617                 :            :     /* Auto-thread-state API */
         618                 :         29 :     status = _PyGILState_Init(interp);
         619         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         620                 :          0 :         return status;
         621                 :            :     }
         622                 :            :
         623                 :         29 :     const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
         624                 :         29 :     init_interp_settings(interp, &config);
         625                 :            :
         626                 :         29 :     PyThreadState *tstate = _PyThreadState_New(interp);
         627         [ -  + ]:         29 :     if (tstate == NULL) {
         628                 :          0 :         return _PyStatus_ERR("can't make first thread");
         629                 :            :     }
         630                 :         29 :     _PyThreadState_Bind(tstate);
         631                 :         29 :     (void) PyThreadState_Swap(tstate);
         632                 :            :
         633                 :         29 :     status = init_interp_create_gil(tstate);
         634         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         635                 :          0 :         return status;
         636                 :            :     }
         637                 :            :
         638                 :         29 :     *tstate_p = tstate;
         639                 :         29 :     return _PyStatus_OK();
         640                 :            : }
         641                 :            :
         642                 :            :
         643                 :            : static PyStatus
         644                 :         29 : pycore_init_global_objects(PyInterpreterState *interp)
         645                 :            : {
         646                 :            :     PyStatus status;
         647                 :            :
         648                 :         29 :     _PyFloat_InitState(interp);
         649                 :            :
         650                 :         29 :     status = _PyUnicode_InitGlobalObjects(interp);
         651         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         652                 :          0 :         return status;
         653                 :            :     }
         654                 :            :
         655                 :         29 :     _PyUnicode_InitState(interp);
         656                 :            :
         657                 :         29 :     return _PyStatus_OK();
         658                 :            : }
         659                 :            :
         660                 :            :
         661                 :            : static PyStatus
         662                 :         29 : pycore_init_types(PyInterpreterState *interp)
         663                 :            : {
         664                 :            :     PyStatus status;
         665                 :            :
         666                 :         29 :     status = _PyTypes_InitTypes(interp);
         667         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         668                 :          0 :         return status;
         669                 :            :     }
         670                 :            :
         671                 :         29 :     status = _PyBytes_InitTypes(interp);
         672         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         673                 :          0 :         return status;
         674                 :            :     }
         675                 :            :
         676                 :         29 :     status = _PyLong_InitTypes(interp);
         677         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         678                 :          0 :         return status;
         679                 :            :     }
         680                 :            :
         681                 :         29 :     status = _PyUnicode_InitTypes(interp);
         682         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         683                 :          0 :         return status;
         684                 :            :     }
         685                 :            :
         686                 :         29 :     status = _PyFloat_InitTypes(interp);
         687         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         688                 :          0 :         return status;
         689                 :            :     }
         690                 :            :
         691                 :         29 :     status = _PyTuple_InitTypes(interp);
         692         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         693                 :          0 :         return status;
         694                 :            :     }
         695                 :            :
         696         [ -  + ]:         29 :     if (_PyExc_InitTypes(interp) < 0) {
         697                 :          0 :         return _PyStatus_ERR("failed to initialize an exception type");
         698                 :            :     }
         699                 :            :
         700                 :         29 :     status = _PyExc_InitGlobalObjects(interp);
         701         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         702                 :          0 :         return status;
         703                 :            :     }
         704                 :            :
         705                 :         29 :     status = _PyExc_InitState(interp);
         706         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         707                 :          0 :         return status;
         708                 :            :     }
         709                 :            :
         710                 :         29 :     status = _PyErr_InitTypes(interp);
         711         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         712                 :          0 :         return status;
         713                 :            :     }
         714                 :            :
         715                 :         29 :     status = _PyContext_Init(interp);
         716         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         717                 :          0 :         return status;
         718                 :            :     }
         719                 :         29 :     return _PyStatus_OK();
         720                 :            : }
         721                 :            :
         722                 :            : static const uint8_t INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = {
         723                 :            :     /* Put a NOP at the start, so that the IP points into
         724                 :            :     * the code, rather than before it */
         725                 :            :     NOP, 0,
         726                 :            :     INTERPRETER_EXIT, 0,
         727                 :            :     /* RESUME at end makes sure that the frame appears incomplete */
         728                 :            :     RESUME, 0
         729                 :            : };
         730                 :            :
         731                 :            : static const _PyShimCodeDef INTERPRETER_TRAMPOLINE_CODEDEF = {
         732                 :            :     INTERPRETER_TRAMPOLINE_INSTRUCTIONS,
         733                 :            :     sizeof(INTERPRETER_TRAMPOLINE_INSTRUCTIONS),
         734                 :            :     1,
         735                 :            :     "<interpreter trampoline>"
         736                 :            : };
         737                 :            :
         738                 :            : static PyStatus
         739                 :         29 : pycore_init_builtins(PyThreadState *tstate)
         740                 :            : {
         741                 :         29 :     PyInterpreterState *interp = tstate->interp;
         742                 :            :
         743                 :         29 :     PyObject *bimod = _PyBuiltin_Init(interp);
         744         [ -  + ]:         29 :     if (bimod == NULL) {
         745                 :          0 :         goto error;
         746                 :            :     }
         747                 :            :
         748                 :         29 :     PyObject *modules = _PyImport_GetModules(interp);
         749         [ -  + ]:         29 :     if (_PyImport_FixupBuiltin(bimod, "builtins", modules) < 0) {
         750                 :          0 :         goto error;
         751                 :            :     }
         752                 :            :
         753                 :         29 :     PyObject *builtins_dict = PyModule_GetDict(bimod);
         754         [ -  + ]:         29 :     if (builtins_dict == NULL) {
         755                 :          0 :         goto error;
         756                 :            :     }
         757                 :         29 :     interp->builtins = Py_NewRef(builtins_dict);
         758                 :            :
         759                 :         29 :     PyObject *isinstance = PyDict_GetItem(builtins_dict, &_Py_ID(isinstance));
         760                 :            :     assert(isinstance);
         761                 :         29 :     interp->callable_cache.isinstance = isinstance;
         762                 :         29 :     PyObject *len = PyDict_GetItem(builtins_dict, &_Py_ID(len));
         763                 :            :     assert(len);
         764                 :         29 :     interp->callable_cache.len = len;
         765                 :         29 :     PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append));
         766                 :            :     assert(list_append);
         767                 :         29 :     interp->callable_cache.list_append = list_append;
         768                 :         29 :     PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__));
         769                 :            :     assert(object__getattribute__);
         770                 :         29 :     interp->callable_cache.object__getattribute__ = object__getattribute__;
         771                 :         29 :     interp->interpreter_trampoline = _Py_MakeShimCode(&INTERPRETER_TRAMPOLINE_CODEDEF);
         772         [ -  + ]:         29 :     if (interp->interpreter_trampoline == NULL) {
         773                 :          0 :         return _PyStatus_ERR("failed to create interpreter trampoline.");
         774                 :            :     }
         775         [ -  + ]:         29 :     if (_PyBuiltins_AddExceptions(bimod) < 0) {
         776                 :          0 :         return _PyStatus_ERR("failed to add exceptions to builtins");
         777                 :            :     }
         778                 :            :
         779                 :         29 :     interp->builtins_copy = PyDict_Copy(interp->builtins);
         780         [ -  + ]:         29 :     if (interp->builtins_copy == NULL) {
         781                 :          0 :         goto error;
         782                 :            :     }
         783                 :         29 :     Py_DECREF(bimod);
         784                 :            :
         785         [ -  + ]:         29 :     if (_PyImport_InitDefaultImportFunc(interp) < 0) {
         786                 :          0 :         goto error;
         787                 :            :     }
         788                 :            :
         789                 :            :     assert(!_PyErr_Occurred(tstate));
         790                 :         29 :     return _PyStatus_OK();
         791                 :            :
         792                 :          0 : error:
         793                 :          0 :     Py_XDECREF(bimod);
         794                 :          0 :     return _PyStatus_ERR("can't initialize builtins module");
         795                 :            : }
         796                 :            :
         797                 :            :
         798                 :            : static PyStatus
         799                 :         29 : pycore_interp_init(PyThreadState *tstate)
         800                 :            : {
         801                 :         29 :     PyInterpreterState *interp = tstate->interp;
         802                 :            :     PyStatus status;
         803                 :         29 :     PyObject *sysmod = NULL;
         804                 :            :
         805                 :            :     // Create singletons before the first PyType_Ready() call, since
         806                 :            :     // PyType_Ready() uses singletons like the Unicode empty string (tp_doc)
         807                 :            :     // and the empty tuple singletons (tp_bases).
         808                 :         29 :     status = pycore_init_global_objects(interp);
         809         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         810                 :          0 :         return status;
         811                 :            :     }
         812                 :            :
         813                 :            :     // The GC must be initialized before the first GC collection.
         814                 :         29 :     status = _PyGC_Init(interp);
         815         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         816                 :          0 :         return status;
         817                 :            :     }
         818                 :            :     // Intern strings in deep-frozen modules first so that others
         819                 :            :     // can use it instead of creating a heap allocated string.
         820         [ -  + ]:         29 :     if (_Py_Deepfreeze_Init() < 0) {
         821                 :          0 :         return _PyStatus_ERR("failed to initialize deep-frozen modules");
         822                 :            :     }
         823                 :            :
         824                 :         29 :     status = pycore_init_types(interp);
         825         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         826                 :          0 :         goto done;
         827                 :            :     }
         828                 :            :
         829         [ -  + ]:         29 :     if (_PyWarnings_InitState(interp) < 0) {
         830                 :          0 :         return _PyStatus_ERR("can't initialize warnings");
         831                 :            :     }
         832                 :            :
         833                 :         29 :     status = _PyAtExit_Init(interp);
         834         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         835                 :          0 :         return status;
         836                 :            :     }
         837                 :            :
         838                 :         29 :     status = _PySys_Create(tstate, &sysmod);
         839         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         840                 :          0 :         goto done;
         841                 :            :     }
         842                 :            :
         843                 :         29 :     status = pycore_init_builtins(tstate);
         844         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         845                 :          0 :         goto done;
         846                 :            :     }
         847                 :            :
         848                 :         29 :     const PyConfig *config = _PyInterpreterState_GetConfig(interp);
         849                 :            :
         850                 :         29 :     status = _PyImport_InitCore(tstate, sysmod, config->_install_importlib);
         851         [ +  - ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         852                 :          0 :         goto done;
         853                 :            :     }
         854                 :            :
         855                 :         29 : done:
         856                 :            :     /* sys.modules['sys'] contains a strong reference to the module */
         857                 :         29 :     Py_XDECREF(sysmod);
         858                 :         29 :     return status;
         859                 :            : }
         860                 :            :
         861                 :            :
         862                 :            : static PyStatus
         863                 :         29 : pyinit_config(_PyRuntimeState *runtime,
         864                 :            :               PyThreadState **tstate_p,
         865                 :            :               const PyConfig *config)
         866                 :            : {
         867                 :         29 :     PyStatus status = pycore_init_runtime(runtime, config);
         868         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         869                 :          0 :         return status;
         870                 :            :     }
         871                 :            :
         872                 :            :     PyThreadState *tstate;
         873                 :         29 :     status = pycore_create_interpreter(runtime, config, &tstate);
         874         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         875                 :          0 :         return status;
         876                 :            :     }
         877                 :         29 :     *tstate_p = tstate;
         878                 :            :
         879                 :         29 :     status = pycore_interp_init(tstate);
         880         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         881                 :          0 :         return status;
         882                 :            :     }
         883                 :            :
         884                 :            :     /* Only when we get here is the runtime core fully initialized */
         885                 :         29 :     runtime->core_initialized = 1;
         886                 :         29 :     return _PyStatus_OK();
         887                 :            : }
         888                 :            :
         889                 :            :
         890                 :            : PyStatus
         891                 :         29 : _Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args)
         892                 :            : {
         893                 :            :     PyStatus status;
         894                 :            :
         895         [ -  + ]:         29 :     if (src_config == NULL) {
         896                 :          0 :         return _PyStatus_ERR("preinitialization config is NULL");
         897                 :            :     }
         898                 :            :
         899                 :         29 :     status = _PyRuntime_Initialize();
         900         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         901                 :          0 :         return status;
         902                 :            :     }
         903                 :         29 :     _PyRuntimeState *runtime = &_PyRuntime;
         904                 :            :
         905         [ -  + ]:         29 :     if (runtime->preinitialized) {
         906                 :            :         /* If it's already configured: ignored the new configuration */
         907                 :          0 :         return _PyStatus_OK();
         908                 :            :     }
         909                 :            :
         910                 :            :     /* Note: preinitialized remains 1 on error, it is only set to 0
         911                 :            :        at exit on success. */
         912                 :         29 :     runtime->preinitializing = 1;
         913                 :            :
         914                 :            :     PyPreConfig config;
         915                 :            :
         916                 :         29 :     status = _PyPreConfig_InitFromPreConfig(&config, src_config);
         917         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         918                 :          0 :         return status;
         919                 :            :     }
         920                 :            :
         921                 :         29 :     status = _PyPreConfig_Read(&config, args);
         922         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         923                 :          0 :         return status;
         924                 :            :     }
         925                 :            :
         926                 :         29 :     status = _PyPreConfig_Write(&config);
         927         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
         928                 :          0 :         return status;
         929                 :            :     }
         930                 :            :
         931                 :         29 :     runtime->preinitializing = 0;
         932                 :         29 :     runtime->preinitialized = 1;
         933                 :         29 :     return _PyStatus_OK();
         934                 :            : }
         935                 :            :
         936                 :            :
         937                 :            : PyStatus
         938                 :          0 : Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv)
         939                 :            : {
         940                 :          0 :     _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
         941                 :          0 :     return _Py_PreInitializeFromPyArgv(src_config, &args);
         942                 :            : }
         943                 :            :
         944                 :            :
         945                 :            : PyStatus
         946                 :          0 : Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv)
         947                 :            : {
         948                 :          0 :     _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
         949                 :          0 :     return _Py_PreInitializeFromPyArgv(src_config, &args);
         950                 :            : }
         951                 :            :
         952                 :            :
         953                 :            : PyStatus
         954                 :          4 : Py_PreInitialize(const PyPreConfig *src_config)
         955                 :            : {
         956                 :          4 :     return _Py_PreInitializeFromPyArgv(src_config, NULL);
         957                 :            : }
         958                 :            :
         959                 :            :
         960                 :            : PyStatus
         961                 :       1913 : _Py_PreInitializeFromConfig(const PyConfig *config,
         962                 :            :                             const _PyArgv *args)
         963                 :            : {
         964                 :            :     assert(config != NULL);
         965                 :            :
         966                 :       1913 :     PyStatus status = _PyRuntime_Initialize();
         967         [ -  + ]:       1913 :     if (_PyStatus_EXCEPTION(status)) {
         968                 :          0 :         return status;
         969                 :            :     }
         970                 :       1913 :     _PyRuntimeState *runtime = &_PyRuntime;
         971                 :            :
         972         [ +  + ]:       1913 :     if (runtime->preinitialized) {
         973                 :            :         /* Already initialized: do nothing */
         974                 :       1888 :         return _PyStatus_OK();
         975                 :            :     }
         976                 :            :
         977                 :            :     PyPreConfig preconfig;
         978                 :            :
         979                 :         25 :     _PyPreConfig_InitFromConfig(&preconfig, config);
         980                 :            :
         981         [ +  + ]:         25 :     if (!config->parse_argv) {
         982                 :          4 :         return Py_PreInitialize(&preconfig);
         983                 :            :     }
         984         [ -  + ]:         21 :     else if (args == NULL) {
         985                 :          0 :         _PyArgv config_args = {
         986                 :            :             .use_bytes_argv = 0,
         987                 :          0 :             .argc = config->argv.length,
         988                 :          0 :             .wchar_argv = config->argv.items};
         989                 :          0 :         return _Py_PreInitializeFromPyArgv(&preconfig, &config_args);
         990                 :            :     }
         991                 :            :     else {
         992                 :         21 :         return _Py_PreInitializeFromPyArgv(&preconfig, args);
         993                 :            :     }
         994                 :            : }
         995                 :            :
         996                 :            :
         997                 :            : /* Begin interpreter initialization
         998                 :            :  *
         999                 :            :  * On return, the first thread and interpreter state have been created,
        1000                 :            :  * but the compiler, signal handling, multithreading and
        1001                 :            :  * multiple interpreter support, and codec infrastructure are not yet
        1002                 :            :  * available.
        1003                 :            :  *
        1004                 :            :  * The import system will support builtin and frozen modules only.
        1005                 :            :  * The only supported io is writing to sys.stderr
        1006                 :            :  *
        1007                 :            :  * If any operation invoked by this function fails, a fatal error is
        1008                 :            :  * issued and the function does not return.
        1009                 :            :  *
        1010                 :            :  * Any code invoked from this function should *not* assume it has access
        1011                 :            :  * to the Python C API (unless the API is explicitly listed as being
        1012                 :            :  * safe to call without calling Py_Initialize first)
        1013                 :            :  */
        1014                 :            : static PyStatus
        1015                 :         29 : pyinit_core(_PyRuntimeState *runtime,
        1016                 :            :             const PyConfig *src_config,
        1017                 :            :             PyThreadState **tstate_p)
        1018                 :            : {
        1019                 :            :     PyStatus status;
        1020                 :            :
        1021                 :         29 :     status = _Py_PreInitializeFromConfig(src_config, NULL);
        1022         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
        1023                 :          0 :         return status;
        1024                 :            :     }
        1025                 :            :
        1026                 :            :     PyConfig config;
        1027                 :         29 :     PyConfig_InitPythonConfig(&config);
        1028                 :            :
        1029                 :         29 :     status = _PyConfig_Copy(&config, src_config);
        1030         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
        1031                 :          0 :         goto done;
        1032                 :            :     }
        1033                 :            :
        1034                 :            :     // Read the configuration, but don't compute the path configuration
        1035                 :            :     // (it is computed in the main init).
        1036                 :         29 :     status = _PyConfig_Read(&config, 0);
        1037         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
        1038                 :          0 :         goto done;
        1039                 :            :     }
        1040                 :            :
        1041         [ +  - ]:         29 :     if (!runtime->core_initialized) {
        1042                 :         29 :         status = pyinit_config(runtime, tstate_p, &config);
        1043                 :            :     }
        1044                 :            :     else {
        1045                 :          0 :         status = pyinit_core_reconfigure(runtime, tstate_p, &config);
        1046                 :            :     }
        1047         [ +  - ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
        1048                 :          0 :         goto done;
        1049                 :            :     }
        1050                 :            :
        1051                 :         29 : done:
        1052                 :         29 :     PyConfig_Clear(&config);
        1053                 :         29 :     return status;
        1054                 :            : }
        1055                 :            :
        1056                 :            :
        1057                 :            : /* Py_Initialize() has already been called: update the main interpreter
        1058                 :            :    configuration. Example of bpo-34008: Py_Main() called after
        1059                 :            :    Py_Initialize(). */
        1060                 :            : static PyStatus
        1061                 :          0 : pyinit_main_reconfigure(PyThreadState *tstate)
        1062                 :            : {
        1063         [ #  # ]:          0 :     if (interpreter_update_config(tstate, 0) < 0) {
        1064                 :          0 :         return _PyStatus_ERR("fail to reconfigure Python");
        1065                 :            :     }
        1066                 :          0 :     return _PyStatus_OK();
        1067                 :            : }
        1068                 :            :
        1069                 :            :
        1070                 :            : static PyStatus
        1071                 :         25 : init_interp_main(PyThreadState *tstate)
        1072                 :            : {
        1073                 :            :     assert(!_PyErr_Occurred(tstate));
        1074                 :            :
        1075                 :            :     PyStatus status;
        1076                 :         25 :     int is_main_interp = _Py_IsMainInterpreter(tstate->interp);
        1077                 :         25 :     PyInterpreterState *interp = tstate->interp;
        1078                 :         25 :     const PyConfig *config = _PyInterpreterState_GetConfig(interp);
        1079                 :            :
        1080         [ -  + ]:         25 :     if (!config->_install_importlib) {
        1081                 :            :         /* Special mode for freeze_importlib: run with no import system
        1082                 :            :          *
        1083                 :            :          * This means anything which needs support from extension modules
        1084                 :            :          * or pure Python code in the standard library won't work.
        1085                 :            :          */
        1086         [ #  # ]:          0 :         if (is_main_interp) {
        1087                 :          0 :             interp->runtime->initialized = 1;
        1088                 :            :         }
        1089                 :          0 :         return _PyStatus_OK();
        1090                 :            :     }
        1091                 :            :
        1092                 :            :     // Initialize the import-related configuration.
        1093                 :         25 :     status = _PyConfig_InitImportConfig(&interp->config);
        1094         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1095                 :          0 :         return status;
        1096                 :            :     }
        1097                 :            :
        1098         [ -  + ]:         25 :     if (interpreter_update_config(tstate, 1) < 0) {
        1099                 :          0 :         return _PyStatus_ERR("failed to update the Python config");
        1100                 :            :     }
        1101                 :            :
        1102                 :         25 :     status = _PyImport_InitExternal(tstate);
        1103         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1104                 :          0 :         return status;
        1105                 :            :     }
        1106                 :            :
        1107         [ +  - ]:         25 :     if (is_main_interp) {
        1108                 :            :         /* initialize the faulthandler module */
        1109                 :         25 :         status = _PyFaulthandler_Init(config->faulthandler);
        1110         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
        1111                 :          0 :             return status;
        1112                 :            :         }
        1113                 :            :     }
        1114                 :            :
        1115                 :         25 :     status = _PyUnicode_InitEncodings(tstate);
        1116         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1117                 :          0 :         return status;
        1118                 :            :     }
        1119                 :            :
        1120         [ +  - ]:         25 :     if (is_main_interp) {
        1121         [ -  + ]:         25 :         if (_PySignal_Init(config->install_signal_handlers) < 0) {
        1122                 :          0 :             return _PyStatus_ERR("can't initialize signals");
        1123                 :            :         }
        1124                 :            :
        1125         [ -  + ]:         25 :         if (_PyTraceMalloc_Init(config->tracemalloc) < 0) {
        1126                 :          0 :             return _PyStatus_ERR("can't initialize tracemalloc");
        1127                 :            :         }
        1128                 :            :
        1129                 :            :
        1130                 :            : #ifdef PY_HAVE_PERF_TRAMPOLINE
        1131         [ -  + ]:         25 :         if (config->perf_profiling) {
        1132   [ #  #  #  # ]:          0 :             if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ||
        1133                 :          0 :                     _PyPerfTrampoline_Init(config->perf_profiling) < 0) {
        1134                 :          0 :                 return _PyStatus_ERR("can't initialize the perf trampoline");
        1135                 :            :             }
        1136                 :            :         }
        1137                 :            : #endif
        1138                 :            :     }
        1139                 :            :
        1140                 :         25 :     status = init_sys_streams(tstate);
        1141         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1142                 :          0 :         return status;
        1143                 :            :     }
        1144                 :            :
        1145                 :         25 :     status = init_set_builtins_open();
        1146         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1147                 :          0 :         return status;
        1148                 :            :     }
        1149                 :            :
        1150                 :         25 :     status = add_main_module(interp);
        1151         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1152                 :          0 :         return status;
        1153                 :            :     }
        1154                 :            :
        1155         [ +  - ]:         25 :     if (is_main_interp) {
        1156                 :            :         /* Initialize warnings. */
        1157                 :         25 :         PyObject *warnoptions = PySys_GetObject("warnoptions");
        1158   [ +  -  -  + ]:         25 :         if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
        1159                 :            :         {
        1160                 :          0 :             PyObject *warnings_module = PyImport_ImportModule("warnings");
        1161         [ #  # ]:          0 :             if (warnings_module == NULL) {
        1162                 :          0 :                 fprintf(stderr, "'import warnings' failed; traceback:\n");
        1163                 :          0 :                 _PyErr_Print(tstate);
        1164                 :            :             }
        1165                 :          0 :             Py_XDECREF(warnings_module);
        1166                 :            :         }
        1167                 :            :
        1168                 :         25 :         interp->runtime->initialized = 1;
        1169                 :            :     }
        1170                 :            :
        1171         [ +  + ]:         25 :     if (config->site_import) {
        1172                 :         24 :         status = init_import_site();
        1173         [ -  + ]:         24 :         if (_PyStatus_EXCEPTION(status)) {
        1174                 :          0 :             return status;
        1175                 :            :         }
        1176                 :            :     }
        1177                 :            :
        1178         [ +  - ]:         25 :     if (is_main_interp) {
        1179                 :            : #ifndef MS_WINDOWS
        1180                 :         25 :         emit_stderr_warning_for_legacy_locale(interp->runtime);
        1181                 :            : #endif
        1182                 :            :     }
        1183                 :            :
        1184                 :            :     assert(!_PyErr_Occurred(tstate));
        1185                 :            :
        1186                 :         25 :     return _PyStatus_OK();
        1187                 :            : }
        1188                 :            :
        1189                 :            :
        1190                 :            : /* Update interpreter state based on supplied configuration settings
        1191                 :            :  *
        1192                 :            :  * After calling this function, most of the restrictions on the interpreter
        1193                 :            :  * are lifted. The only remaining incomplete settings are those related
        1194                 :            :  * to the main module (sys.argv[0], __main__ metadata)
        1195                 :            :  *
        1196                 :            :  * Calling this when the interpreter is not initializing, is already
        1197                 :            :  * initialized or without a valid current thread state is a fatal error.
        1198                 :            :  * Other errors should be reported as normal Python exceptions with a
        1199                 :            :  * non-zero return code.
        1200                 :            :  */
        1201                 :            : static PyStatus
        1202                 :         25 : pyinit_main(PyThreadState *tstate)
        1203                 :            : {
        1204                 :         25 :     PyInterpreterState *interp = tstate->interp;
        1205         [ -  + ]:         25 :     if (!interp->runtime->core_initialized) {
        1206                 :          0 :         return _PyStatus_ERR("runtime core not initialized");
        1207                 :            :     }
        1208                 :            :
        1209         [ -  + ]:         25 :     if (interp->runtime->initialized) {
        1210                 :          0 :         return pyinit_main_reconfigure(tstate);
        1211                 :            :     }
        1212                 :            :
        1213                 :         25 :     PyStatus status = init_interp_main(tstate);
        1214         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        1215                 :          0 :         return status;
        1216                 :            :     }
        1217                 :         25 :     return _PyStatus_OK();
        1218                 :            : }
        1219                 :            :
        1220                 :            :
        1221                 :            : PyStatus
        1222                 :         29 : Py_InitializeFromConfig(const PyConfig *config)
        1223                 :            : {
        1224         [ -  + ]:         29 :     if (config == NULL) {
        1225                 :          0 :         return _PyStatus_ERR("initialization config is NULL");
        1226                 :            :     }
        1227                 :            :
        1228                 :            :     PyStatus status;
        1229                 :            :
        1230                 :         29 :     status = _PyRuntime_Initialize();
        1231         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
        1232                 :          0 :         return status;
        1233                 :            :     }
        1234                 :         29 :     _PyRuntimeState *runtime = &_PyRuntime;
        1235                 :            :
        1236                 :         29 :     PyThreadState *tstate = NULL;
        1237                 :         29 :     status = pyinit_core(runtime, config, &tstate);
        1238         [ -  + ]:         29 :     if (_PyStatus_EXCEPTION(status)) {
        1239                 :          0 :         return status;
        1240                 :            :     }
        1241                 :         29 :     config = _PyInterpreterState_GetConfig(tstate->interp);
        1242                 :            :
        1243         [ +  + ]:         29 :     if (config->_init_main) {
        1244                 :         25 :         status = pyinit_main(tstate);
        1245         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
        1246                 :          0 :             return status;
        1247                 :            :         }
        1248                 :            :     }
        1249                 :            :
        1250                 :         29 :     return _PyStatus_OK();
        1251                 :            : }
        1252                 :            :
        1253                 :            :
        1254                 :            : void
        1255                 :          0 : Py_InitializeEx(int install_sigs)
        1256                 :            : {
        1257                 :            :     PyStatus status;
        1258                 :            :
        1259                 :          0 :     status = _PyRuntime_Initialize();
        1260         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        1261                 :          0 :         Py_ExitStatusException(status);
        1262                 :            :     }
        1263                 :          0 :     _PyRuntimeState *runtime = &_PyRuntime;
        1264                 :            :
        1265         [ #  # ]:          0 :     if (runtime->initialized) {
        1266                 :            :         /* bpo-33932: Calling Py_Initialize() twice does nothing. */
        1267                 :          0 :         return;
        1268                 :            :     }
        1269                 :            :
        1270                 :            :     PyConfig config;
        1271                 :          0 :     _PyConfig_InitCompatConfig(&config);
        1272                 :            :
        1273                 :          0 :     config.install_signal_handlers = install_sigs;
        1274                 :            :
        1275                 :          0 :     status = Py_InitializeFromConfig(&config);
        1276                 :          0 :     PyConfig_Clear(&config);
        1277         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        1278                 :          0 :         Py_ExitStatusException(status);
        1279                 :            :     }
        1280                 :            : }
        1281                 :            :
        1282                 :            : void
        1283                 :          0 : Py_Initialize(void)
        1284                 :            : {
        1285                 :          0 :     Py_InitializeEx(1);
        1286                 :          0 : }
        1287                 :            :
        1288                 :            :
        1289                 :            : PyStatus
        1290                 :          0 : _Py_InitializeMain(void)
        1291                 :            : {
        1292                 :          0 :     PyStatus status = _PyRuntime_Initialize();
        1293         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        1294                 :          0 :         return status;
        1295                 :            :     }
        1296                 :          0 :     _PyRuntimeState *runtime = &_PyRuntime;
        1297                 :          0 :     PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
        1298                 :          0 :     return pyinit_main(tstate);
        1299                 :            : }
        1300                 :            :
        1301                 :            :
        1302                 :            : static void
        1303                 :         25 : finalize_modules_delete_special(PyThreadState *tstate, int verbose)
        1304                 :            : {
        1305                 :            :     // List of names to clear in sys
        1306                 :            :     static const char * const sys_deletes[] = {
        1307                 :            :         "path", "argv", "ps1", "ps2", "last_exc",
        1308                 :            :         "last_type", "last_value", "last_traceback",
        1309                 :            :         "__interactivehook__",
        1310                 :            :         // path_hooks and path_importer_cache are cleared
        1311                 :            :         // by _PyImport_FiniExternal().
        1312                 :            :         // XXX Clear meta_path in _PyImport_FiniCore().
        1313                 :            :         "meta_path",
        1314                 :            :         NULL
        1315                 :            :     };
        1316                 :            :
        1317                 :            :     static const char * const sys_files[] = {
        1318                 :            :         "stdin", "__stdin__",
        1319                 :            :         "stdout", "__stdout__",
        1320                 :            :         "stderr", "__stderr__",
        1321                 :            :         NULL
        1322                 :            :     };
        1323                 :            :
        1324                 :         25 :     PyInterpreterState *interp = tstate->interp;
        1325         [ -  + ]:         25 :     if (verbose) {
        1326                 :          0 :         PySys_WriteStderr("# clear builtins._\n");
        1327                 :            :     }
        1328         [ -  + ]:         25 :     if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) {
        1329                 :          0 :         PyErr_WriteUnraisable(NULL);
        1330                 :            :     }
        1331                 :            :
        1332                 :            :     const char * const *p;
        1333         [ +  + ]:        275 :     for (p = sys_deletes; *p != NULL; p++) {
        1334         [ -  + ]:        250 :         if (_PySys_ClearAttrString(interp, *p, verbose) < 0) {
        1335                 :          0 :             PyErr_WriteUnraisable(NULL);
        1336                 :            :         }
        1337                 :            :     }
        1338         [ +  + ]:        100 :     for (p = sys_files; *p != NULL; p+=2) {
        1339                 :         75 :         const char *name = p[0];
        1340                 :         75 :         const char *orig_name = p[1];
        1341         [ -  + ]:         75 :         if (verbose) {
        1342                 :          0 :             PySys_WriteStderr("# restore sys.%s\n", name);
        1343                 :            :         }
        1344                 :         75 :         PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict,
        1345                 :            :                                                          orig_name);
        1346         [ -  + ]:         75 :         if (value == NULL) {
        1347         [ #  # ]:          0 :             if (_PyErr_Occurred(tstate)) {
        1348                 :          0 :                 PyErr_WriteUnraisable(NULL);
        1349                 :            :             }
        1350                 :          0 :             value = Py_None;
        1351                 :            :         }
        1352         [ -  + ]:         75 :         if (PyDict_SetItemString(interp->sysdict, name, value) < 0) {
        1353                 :          0 :             PyErr_WriteUnraisable(NULL);
        1354                 :            :         }
        1355                 :            :     }
        1356                 :         25 : }
        1357                 :            :
        1358                 :            :
        1359                 :            : static PyObject*
        1360                 :         25 : finalize_remove_modules(PyObject *modules, int verbose)
        1361                 :            : {
        1362                 :         25 :     PyObject *weaklist = PyList_New(0);
        1363         [ -  + ]:         25 :     if (weaklist == NULL) {
        1364                 :          0 :         PyErr_WriteUnraisable(NULL);
        1365                 :            :     }
        1366                 :            :
        1367                 :            : #define STORE_MODULE_WEAKREF(name, mod) \
        1368                 :            :         if (weaklist != NULL) { \
        1369                 :            :             PyObject *wr = PyWeakref_NewRef(mod, NULL); \
        1370                 :            :             if (wr) { \
        1371                 :            :                 PyObject *tup = PyTuple_Pack(2, name, wr); \
        1372                 :            :                 if (!tup || PyList_Append(weaklist, tup) < 0) { \
        1373                 :            :                     PyErr_WriteUnraisable(NULL); \
        1374                 :            :                 } \
        1375                 :            :                 Py_XDECREF(tup); \
        1376                 :            :                 Py_DECREF(wr); \
        1377                 :            :             } \
        1378                 :            :             else { \
        1379                 :            :                 PyErr_WriteUnraisable(NULL); \
        1380                 :            :             } \
        1381                 :            :         }
        1382                 :            :
        1383                 :            : #define CLEAR_MODULE(name, mod) \
        1384                 :            :         if (PyModule_Check(mod)) { \
        1385                 :            :             if (verbose && PyUnicode_Check(name)) { \
        1386                 :            :                 PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
        1387                 :            :             } \
        1388                 :            :             STORE_MODULE_WEAKREF(name, mod); \
        1389                 :            :             if (PyObject_SetItem(modules, name, Py_None) < 0) { \
        1390                 :            :                 PyErr_WriteUnraisable(NULL); \
        1391                 :            :             } \
        1392                 :            :         }
        1393                 :            :
        1394         [ +  - ]:         25 :     if (PyDict_CheckExact(modules)) {
        1395                 :         25 :         Py_ssize_t pos = 0;
        1396                 :            :         PyObject *key, *value;
        1397         [ +  + ]:       1225 :         while (PyDict_Next(modules, &pos, &key, &value)) {
        1398   [ +  +  -  +  :       1200 :             CLEAR_MODULE(key, value);
              -  -  +  -  +
              -  +  -  -  +
                       -  + ]
        1399                 :            :         }
        1400                 :            :     }
        1401                 :            :     else {
        1402                 :          0 :         PyObject *iterator = PyObject_GetIter(modules);
        1403         [ #  # ]:          0 :         if (iterator == NULL) {
        1404                 :          0 :             PyErr_WriteUnraisable(NULL);
        1405                 :            :         }
        1406                 :            :         else {
        1407                 :            :             PyObject *key;
        1408         [ #  # ]:          0 :             while ((key = PyIter_Next(iterator))) {
        1409                 :          0 :                 PyObject *value = PyObject_GetItem(modules, key);
        1410         [ #  # ]:          0 :                 if (value == NULL) {
        1411                 :          0 :                     PyErr_WriteUnraisable(NULL);
        1412                 :          0 :                     continue;
        1413                 :            :                 }
        1414   [ #  #  #  #  :          0 :                 CLEAR_MODULE(key, value);
              #  #  #  #  #
              #  #  #  #  #
                       #  # ]
        1415                 :          0 :                 Py_DECREF(value);
        1416                 :          0 :                 Py_DECREF(key);
        1417                 :            :             }
        1418         [ #  # ]:          0 :             if (PyErr_Occurred()) {
        1419                 :          0 :                 PyErr_WriteUnraisable(NULL);
        1420                 :            :             }
        1421                 :          0 :             Py_DECREF(iterator);
        1422                 :            :         }
        1423                 :            :     }
        1424                 :            : #undef CLEAR_MODULE
        1425                 :            : #undef STORE_MODULE_WEAKREF
        1426                 :            :
        1427                 :         25 :     return weaklist;
        1428                 :            : }
        1429                 :            :
        1430                 :            :
        1431                 :            : static void
        1432                 :         25 : finalize_clear_modules_dict(PyObject *modules)
        1433                 :            : {
        1434         [ +  - ]:         25 :     if (PyDict_CheckExact(modules)) {
        1435                 :         25 :         PyDict_Clear(modules);
        1436                 :            :     }
        1437                 :            :     else {
        1438         [ #  # ]:          0 :         if (PyObject_CallMethodNoArgs(modules, &_Py_ID(clear)) == NULL) {
        1439                 :          0 :             PyErr_WriteUnraisable(NULL);
        1440                 :            :         }
        1441                 :            :     }
        1442                 :         25 : }
        1443                 :            :
        1444                 :            :
        1445                 :            : static void
        1446                 :         25 : finalize_restore_builtins(PyThreadState *tstate)
        1447                 :            : {
        1448                 :         25 :     PyInterpreterState *interp = tstate->interp;
        1449                 :         25 :     PyObject *dict = PyDict_Copy(interp->builtins);
        1450         [ -  + ]:         25 :     if (dict == NULL) {
        1451                 :          0 :         PyErr_WriteUnraisable(NULL);
        1452                 :            :     }
        1453                 :         25 :     PyDict_Clear(interp->builtins);
        1454         [ -  + ]:         25 :     if (PyDict_Update(interp->builtins, interp->builtins_copy)) {
        1455                 :          0 :         PyErr_WriteUnraisable(NULL);
        1456                 :            :     }
        1457                 :         25 :     Py_XDECREF(dict);
        1458                 :         25 : }
        1459                 :            :
        1460                 :            :
        1461                 :            : static void
        1462                 :         25 : finalize_modules_clear_weaklist(PyInterpreterState *interp,
        1463                 :            :                                 PyObject *weaklist, int verbose)
        1464                 :            : {
        1465                 :            :     // First clear modules imported later
        1466         [ +  + ]:       1219 :     for (Py_ssize_t i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) {
        1467                 :       1194 :         PyObject *tup = PyList_GET_ITEM(weaklist, i);
        1468                 :       1194 :         PyObject *name = PyTuple_GET_ITEM(tup, 0);
        1469                 :       1194 :         PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1));
        1470         [ +  + ]:       1194 :         if (mod == Py_None) {
        1471                 :        653 :             continue;
        1472                 :            :         }
        1473                 :            :         assert(PyModule_Check(mod));
        1474                 :        541 :         PyObject *dict = PyModule_GetDict(mod);
        1475   [ +  +  +  + ]:        541 :         if (dict == interp->builtins || dict == interp->sysdict) {
        1476                 :         50 :             continue;
        1477                 :            :         }
        1478                 :        491 :         Py_INCREF(mod);
        1479   [ -  +  -  - ]:        491 :         if (verbose && PyUnicode_Check(name)) {
        1480                 :          0 :             PySys_FormatStderr("# cleanup[3] wiping %U\n", name);
        1481                 :            :         }
        1482                 :        491 :         _PyModule_Clear(mod);
        1483                 :        491 :         Py_DECREF(mod);
        1484                 :            :     }
        1485                 :         25 : }
        1486                 :            :
        1487                 :            :
        1488                 :            : static void
        1489                 :         25 : finalize_clear_sys_builtins_dict(PyInterpreterState *interp, int verbose)
        1490                 :            : {
        1491                 :            :     // Clear sys dict
        1492         [ -  + ]:         25 :     if (verbose) {
        1493                 :          0 :         PySys_FormatStderr("# cleanup[3] wiping sys\n");
        1494                 :            :     }
        1495                 :         25 :     _PyModule_ClearDict(interp->sysdict);
        1496                 :            :
        1497                 :            :     // Clear builtins dict
        1498         [ -  + ]:         25 :     if (verbose) {
        1499                 :          0 :         PySys_FormatStderr("# cleanup[3] wiping builtins\n");
        1500                 :            :     }
        1501                 :         25 :     _PyModule_ClearDict(interp->builtins);
        1502                 :         25 : }
        1503                 :            :
        1504                 :            :
        1505                 :            : /* Clear modules, as good as we can */
        1506                 :            : // XXX Move most of this to import.c.
        1507                 :            : static void
        1508                 :         25 : finalize_modules(PyThreadState *tstate)
        1509                 :            : {
        1510                 :         25 :     PyInterpreterState *interp = tstate->interp;
        1511                 :         25 :     PyObject *modules = _PyImport_GetModules(interp);
        1512         [ -  + ]:         25 :     if (modules == NULL) {
        1513                 :            :         // Already done
        1514                 :          0 :         return;
        1515                 :            :     }
        1516                 :         25 :     int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
        1517                 :            :
        1518                 :            :     // Delete some special builtins._ and sys attributes first.  These are
        1519                 :            :     // common places where user values hide and people complain when their
        1520                 :            :     // destructors fail.  Since the modules containing them are
        1521                 :            :     // deleted *last* of all, they would come too late in the normal
        1522                 :            :     // destruction order.  Sigh.
        1523                 :            :     //
        1524                 :            :     // XXX Perhaps these precautions are obsolete. Who knows?
        1525                 :         25 :     finalize_modules_delete_special(tstate, verbose);
        1526                 :            :
        1527                 :            :     // Remove all modules from sys.modules, hoping that garbage collection
        1528                 :            :     // can reclaim most of them: set all sys.modules values to None.
        1529                 :            :     //
        1530                 :            :     // We prepare a list which will receive (name, weakref) tuples of
        1531                 :            :     // modules when they are removed from sys.modules.  The name is used
        1532                 :            :     // for diagnosis messages (in verbose mode), while the weakref helps
        1533                 :            :     // detect those modules which have been held alive.
        1534                 :         25 :     PyObject *weaklist = finalize_remove_modules(modules, verbose);
        1535                 :            :
        1536                 :            :     // Clear the modules dict
        1537                 :         25 :     finalize_clear_modules_dict(modules);
        1538                 :            :
        1539                 :            :     // Restore the original builtins dict, to ensure that any
        1540                 :            :     // user data gets cleared.
        1541                 :         25 :     finalize_restore_builtins(tstate);
        1542                 :            :
        1543                 :            :     // Collect garbage
        1544                 :         25 :     _PyGC_CollectNoFail(tstate);
        1545                 :            :
        1546                 :            :     // Dump GC stats before it's too late, since it uses the warnings
        1547                 :            :     // machinery.
        1548                 :         25 :     _PyGC_DumpShutdownStats(interp);
        1549                 :            :
        1550         [ +  - ]:         25 :     if (weaklist != NULL) {
        1551                 :            :         // Now, if there are any modules left alive, clear their globals to
        1552                 :            :         // minimize potential leaks.  All C extension modules actually end
        1553                 :            :         // up here, since they are kept alive in the interpreter state.
        1554                 :            :         //
        1555                 :            :         // The special treatment of "builtins" here is because even
        1556                 :            :         // when it's not referenced as a module, its dictionary is
        1557                 :            :         // referenced by almost every module's __builtins__.  Since
        1558                 :            :         // deleting a module clears its dictionary (even if there are
        1559                 :            :         // references left to it), we need to delete the "builtins"
        1560                 :            :         // module last.  Likewise, we don't delete sys until the very
        1561                 :            :         // end because it is implicitly referenced (e.g. by print).
        1562                 :            :         //
        1563                 :            :         // Since dict is ordered in CPython 3.6+, modules are saved in
        1564                 :            :         // importing order.  First clear modules imported later.
        1565                 :         25 :         finalize_modules_clear_weaklist(interp, weaklist, verbose);
        1566                 :         25 :         Py_DECREF(weaklist);
        1567                 :            :     }
        1568                 :            :
        1569                 :            :     // Clear sys and builtins modules dict
        1570                 :         25 :     finalize_clear_sys_builtins_dict(interp, verbose);
        1571                 :            :
        1572                 :            :     // Clear module dict copies stored in the interpreter state:
        1573                 :            :     // clear PyInterpreterState.modules_by_index and
        1574                 :            :     // clear PyModuleDef.m_base.m_copy (of extensions not using the multi-phase
        1575                 :            :     // initialization API)
        1576                 :         25 :     _PyImport_ClearModulesByIndex(interp);
        1577                 :            :
        1578                 :            :     // Clear and delete the modules directory.  Actual modules will
        1579                 :            :     // still be there only if imported during the execution of some
        1580                 :            :     // destructor.
        1581                 :         25 :     _PyImport_ClearModules(interp);
        1582                 :            :
        1583                 :            :     // Collect garbage once more
        1584                 :         25 :     _PyGC_CollectNoFail(tstate);
        1585                 :            : }
        1586                 :            :
        1587                 :            :
        1588                 :            : /* Flush stdout and stderr */
        1589                 :            :
        1590                 :            : static int
        1591                 :         50 : file_is_closed(PyObject *fobj)
        1592                 :            : {
        1593                 :            :     int r;
        1594                 :         50 :     PyObject *tmp = PyObject_GetAttrString(fobj, "closed");
        1595         [ -  + ]:         50 :     if (tmp == NULL) {
        1596                 :          0 :         PyErr_Clear();
        1597                 :          0 :         return 0;
        1598                 :            :     }
        1599                 :         50 :     r = PyObject_IsTrue(tmp);
        1600                 :         50 :     Py_DECREF(tmp);
        1601         [ -  + ]:         50 :     if (r < 0)
        1602                 :          0 :         PyErr_Clear();
        1603                 :         50 :     return r > 0;
        1604                 :            : }
        1605                 :            :
        1606                 :            :
        1607                 :            : static int
        1608                 :         50 : flush_std_files(void)
        1609                 :            : {
        1610                 :         50 :     PyThreadState *tstate = _PyThreadState_GET();
        1611                 :         50 :     PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout));
        1612                 :         50 :     PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
        1613                 :            :     PyObject *tmp;
        1614                 :         50 :     int status = 0;
        1615                 :            :
        1616   [ +  -  +  +  :         50 :     if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
                       +  - ]
        1617                 :         25 :         tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush));
        1618         [ -  + ]:         25 :         if (tmp == NULL) {
        1619                 :          0 :             PyErr_WriteUnraisable(fout);
        1620                 :          0 :             status = -1;
        1621                 :            :         }
        1622                 :            :         else
        1623                 :         25 :             Py_DECREF(tmp);
        1624                 :            :     }
        1625                 :            :
        1626   [ +  -  +  +  :         50 :     if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
                       +  - ]
        1627                 :         25 :         tmp = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush));
        1628         [ -  + ]:         25 :         if (tmp == NULL) {
        1629                 :          0 :             PyErr_Clear();
        1630                 :          0 :             status = -1;
        1631                 :            :         }
        1632                 :            :         else
        1633                 :         25 :             Py_DECREF(tmp);
        1634                 :            :     }
        1635                 :            :
        1636                 :         50 :     return status;
        1637                 :            : }
        1638                 :            :
        1639                 :            : /* Undo the effect of Py_Initialize().
        1640                 :            :
        1641                 :            :    Beware: if multiple interpreter and/or thread states exist, these
        1642                 :            :    are not wiped out; only the current thread and interpreter state
        1643                 :            :    are deleted.  But since everything else is deleted, those other
        1644                 :            :    interpreter and thread states should no longer be used.
        1645                 :            :
        1646                 :            :    (XXX We should do better, e.g. wipe out all interpreters and
        1647                 :            :    threads.)
        1648                 :            :
        1649                 :            :    Locking: as above.
        1650                 :            :
        1651                 :            : */
        1652                 :            :
        1653                 :            :
        1654                 :            : static void
        1655                 :         25 : finalize_interp_types(PyInterpreterState *interp)
        1656                 :            : {
        1657                 :         25 :     _PyUnicode_FiniTypes(interp);
        1658                 :         25 :     _PySys_Fini(interp);
        1659                 :         25 :     _PyExc_Fini(interp);
        1660                 :         25 :     _PyAsyncGen_Fini(interp);
        1661                 :         25 :     _PyContext_Fini(interp);
        1662                 :         25 :     _PyFloat_FiniType(interp);
        1663                 :         25 :     _PyLong_FiniTypes(interp);
        1664                 :         25 :     _PyThread_FiniType(interp);
        1665                 :         25 :     _PyErr_FiniTypes(interp);
        1666                 :         25 :     _PyTypes_FiniTypes(interp);
        1667                 :            :
        1668                 :         25 :     _PyTypes_Fini(interp);
        1669                 :            :
        1670                 :            :     // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses
        1671                 :            :     // a dict internally.
        1672                 :         25 :     _PyUnicode_ClearInterned(interp);
        1673                 :            :
        1674                 :         25 :     _PyDict_Fini(interp);
        1675                 :         25 :     _PyList_Fini(interp);
        1676                 :         25 :     _PyTuple_Fini(interp);
        1677                 :            :
        1678                 :         25 :     _PySlice_Fini(interp);
        1679                 :            :
        1680                 :         25 :     _PyUnicode_Fini(interp);
        1681                 :         25 :     _PyFloat_Fini(interp);
        1682                 :            : #ifdef Py_DEBUG
        1683                 :            :     _PyStaticObjects_CheckRefcnt(interp);
        1684                 :            : #endif
        1685                 :         25 : }
        1686                 :            :
        1687                 :            :
        1688                 :            : static void
        1689                 :         25 : finalize_interp_clear(PyThreadState *tstate)
        1690                 :            : {
        1691                 :         25 :     int is_main_interp = _Py_IsMainInterpreter(tstate->interp);
        1692                 :            :
        1693                 :         25 :     _PyExc_ClearExceptionGroupType(tstate->interp);
        1694                 :            :
        1695                 :            :     /* Clear interpreter state and all thread states */
        1696                 :         25 :     _PyInterpreterState_Clear(tstate);
        1697                 :            :
        1698         [ +  - ]:         25 :     if (is_main_interp) {
        1699                 :         25 :         _PyIO_Fini();
        1700                 :            :     }
        1701                 :            :
        1702                 :            :     /* Clear all loghooks */
        1703                 :            :     /* Both _PySys_Audit function and users still need PyObject, such as tuple.
        1704                 :            :        Call _PySys_ClearAuditHooks when PyObject available. */
        1705         [ +  - ]:         25 :     if (is_main_interp) {
        1706                 :         25 :         _PySys_ClearAuditHooks(tstate);
        1707                 :            :     }
        1708                 :            :
        1709         [ +  - ]:         25 :     if (is_main_interp) {
        1710                 :         25 :         _Py_HashRandomization_Fini();
        1711                 :         25 :         _PyArg_Fini();
        1712                 :         25 :         _Py_ClearFileSystemEncoding();
        1713                 :         25 :         _Py_Deepfreeze_Fini();
        1714                 :         25 :         _PyPerfTrampoline_Fini();
        1715                 :            :     }
        1716                 :            :
        1717                 :         25 :     finalize_interp_types(tstate->interp);
        1718                 :         25 : }
        1719                 :            :
        1720                 :            :
        1721                 :            : static void
        1722                 :         25 : finalize_interp_delete(PyInterpreterState *interp)
        1723                 :            : {
        1724                 :            :     /* Cleanup auto-thread-state */
        1725                 :         25 :     _PyGILState_Fini(interp);
        1726                 :            :
        1727                 :            :     /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can
        1728                 :            :        fail when it is being awaited by another running daemon thread (see
        1729                 :            :        bpo-9901). Instead pycore_create_interpreter() destroys the previously
        1730                 :            :        created GIL, which ensures that Py_Initialize / Py_FinalizeEx can be
        1731                 :            :        called multiple times. */
        1732                 :            :
        1733                 :         25 :     PyInterpreterState_Delete(interp);
        1734                 :         25 : }
        1735                 :            :
        1736                 :            :
        1737                 :            : int
        1738                 :         29 : Py_FinalizeEx(void)
        1739                 :            : {
        1740                 :         29 :     int status = 0;
        1741                 :            :
        1742                 :         29 :     _PyRuntimeState *runtime = &_PyRuntime;
        1743         [ +  + ]:         29 :     if (!runtime->initialized) {
        1744                 :          4 :         return status;
        1745                 :            :     }
        1746                 :            :
        1747                 :            :     /* Get current thread state and interpreter pointer */
        1748                 :         25 :     PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
        1749                 :            :     // XXX assert(_Py_IsMainInterpreter(tstate->interp));
        1750                 :            :     // XXX assert(_Py_IsMainThread());
        1751                 :            :
        1752                 :            :     // Block some operations.
        1753                 :         25 :     tstate->interp->finalizing = 1;
        1754                 :            :
        1755                 :            :     // Wrap up existing "threading"-module-created, non-daemon threads.
        1756                 :         25 :     wait_for_thread_shutdown(tstate);
        1757                 :            :
        1758                 :            :     // Make any remaining pending calls.
        1759                 :         25 :     _Py_FinishPendingCalls(tstate);
        1760                 :            :
        1761                 :            :     /* The interpreter is still entirely intact at this point, and the
        1762                 :            :      * exit funcs may be relying on that.  In particular, if some thread
        1763                 :            :      * or exit func is still waiting to do an import, the import machinery
        1764                 :            :      * expects Py_IsInitialized() to return true.  So don't say the
        1765                 :            :      * runtime is uninitialized until after the exit funcs have run.
        1766                 :            :      * Note that Threading.py uses an exit func to do a join on all the
        1767                 :            :      * threads created thru it, so this also protects pending imports in
        1768                 :            :      * the threads created via Threading.
        1769                 :            :      */
        1770                 :            :
        1771                 :         25 :     _PyAtExit_Call(tstate->interp);
        1772                 :            :
        1773                 :            :     /* Copy the core config, PyInterpreterState_Delete() free
        1774                 :            :        the core config memory */
        1775                 :            : #ifdef Py_REF_DEBUG
        1776                 :            :     int show_ref_count = tstate->interp->config.show_ref_count;
        1777                 :            : #endif
        1778                 :            : #ifdef Py_TRACE_REFS
        1779                 :            :     int dump_refs = tstate->interp->config.dump_refs;
        1780                 :            :     wchar_t *dump_refs_file = tstate->interp->config.dump_refs_file;
        1781                 :            : #endif
        1782                 :            : #ifdef WITH_PYMALLOC
        1783                 :         25 :     int malloc_stats = tstate->interp->config.malloc_stats;
        1784                 :            : #endif
        1785                 :            :
        1786                 :            :     /* Remaining daemon threads will automatically exit
        1787                 :            :        when they attempt to take the GIL (ex: PyEval_RestoreThread()). */
        1788                 :         25 :     _PyRuntimeState_SetFinalizing(runtime, tstate);
        1789                 :         25 :     runtime->initialized = 0;
        1790                 :         25 :     runtime->core_initialized = 0;
        1791                 :            :
        1792                 :            :     // XXX Call something like _PyImport_Disable() here?
        1793                 :            :
        1794                 :            :     /* Destroy the state of all threads of the interpreter, except of the
        1795                 :            :        current thread. In practice, only daemon threads should still be alive,
        1796                 :            :        except if wait_for_thread_shutdown() has been cancelled by CTRL+C.
        1797                 :            :        Clear frames of other threads to call objects destructors. Destructors
        1798                 :            :        will be called in the current Python thread. Since
        1799                 :            :        _PyRuntimeState_SetFinalizing() has been called, no other Python thread
        1800                 :            :        can take the GIL at this point: if they try, they will exit
        1801                 :            :        immediately. */
        1802                 :         25 :     _PyThreadState_DeleteExcept(tstate);
        1803                 :            :
        1804                 :            :     /* At this point no Python code should be running at all.
        1805                 :            :        The only thread state left should be the main thread of the main
        1806                 :            :        interpreter (AKA tstate), in which this code is running right now.
        1807                 :            :        There may be other OS threads running but none of them will have
        1808                 :            :        thread states associated with them, nor will be able to create
        1809                 :            :        new thread states.
        1810                 :            :
        1811                 :            :        Thus tstate is the only possible thread state from here on out.
        1812                 :            :        It may still be used during finalization to run Python code as
        1813                 :            :        needed or provide runtime state (e.g. sys.modules) but that will
        1814                 :            :        happen sparingly.  Furthermore, the order of finalization aims
        1815                 :            :        to not need a thread (or interpreter) state as soon as possible.
        1816                 :            :      */
        1817                 :            :     // XXX Make sure we are preventing the creating of any new thread states
        1818                 :            :     // (or interpreters).
        1819                 :            :
        1820                 :            :     /* Flush sys.stdout and sys.stderr */
        1821         [ -  + ]:         25 :     if (flush_std_files() < 0) {
        1822                 :          0 :         status = -1;
        1823                 :            :     }
        1824                 :            :
        1825                 :            :     /* Disable signal handling */
        1826                 :         25 :     _PySignal_Fini();
        1827                 :            :
        1828                 :            :     /* Collect garbage.  This may call finalizers; it's nice to call these
        1829                 :            :      * before all modules are destroyed.
        1830                 :            :      * XXX If a __del__ or weakref callback is triggered here, and tries to
        1831                 :            :      * XXX import a module, bad things can happen, because Python no
        1832                 :            :      * XXX longer believes it's initialized.
        1833                 :            :      * XXX     Fatal Python error: Interpreter not initialized (version mismatch?)
        1834                 :            :      * XXX is easy to provoke that way.  I've also seen, e.g.,
        1835                 :            :      * XXX     Exception exceptions.ImportError: 'No module named sha'
        1836                 :            :      * XXX         in <function callback at 0x008F5718> ignored
        1837                 :            :      * XXX but I'm unclear on exactly how that one happens.  In any case,
        1838                 :            :      * XXX I haven't seen a real-life report of either of these.
        1839                 :            :      */
        1840                 :         25 :     PyGC_Collect();
        1841                 :            :
        1842                 :            :     /* Destroy all modules */
        1843                 :         25 :     _PyImport_FiniExternal(tstate->interp);
        1844                 :         25 :     finalize_modules(tstate);
        1845                 :            :
        1846                 :            :     /* Print debug stats if any */
        1847                 :         25 :     _PyEval_Fini();
        1848                 :            :
        1849                 :            :     /* Flush sys.stdout and sys.stderr (again, in case more was printed) */
        1850         [ -  + ]:         25 :     if (flush_std_files() < 0) {
        1851                 :          0 :         status = -1;
        1852                 :            :     }
        1853                 :            :
        1854                 :            :     /* Collect final garbage.  This disposes of cycles created by
        1855                 :            :      * class definitions, for example.
        1856                 :            :      * XXX This is disabled because it caused too many problems.  If
        1857                 :            :      * XXX a __del__ or weakref callback triggers here, Python code has
        1858                 :            :      * XXX a hard time running, because even the sys module has been
        1859                 :            :      * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc).
        1860                 :            :      * XXX One symptom is a sequence of information-free messages
        1861                 :            :      * XXX coming from threads (if a __del__ or callback is invoked,
        1862                 :            :      * XXX other threads can execute too, and any exception they encounter
        1863                 :            :      * XXX triggers a comedy of errors as subsystem after subsystem
        1864                 :            :      * XXX fails to find what it *expects* to find in sys to help report
        1865                 :            :      * XXX the exception and consequent unexpected failures).  I've also
        1866                 :            :      * XXX seen segfaults then, after adding print statements to the
        1867                 :            :      * XXX Python code getting called.
        1868                 :            :      */
        1869                 :            : #if 0
        1870                 :            :     _PyGC_CollectIfEnabled();
        1871                 :            : #endif
        1872                 :            :
        1873                 :            :     /* Disable tracemalloc after all Python objects have been destroyed,
        1874                 :            :        so it is possible to use tracemalloc in objects destructor. */
        1875                 :         25 :     _PyTraceMalloc_Fini();
        1876                 :            :
        1877                 :            :     /* Finalize any remaining import state */
        1878                 :            :     // XXX Move these up to where finalize_modules() is currently.
        1879                 :         25 :     _PyImport_FiniCore(tstate->interp);
        1880                 :         25 :     _PyImport_Fini();
        1881                 :            :
        1882                 :            :     /* unload faulthandler module */
        1883                 :         25 :     _PyFaulthandler_Fini();
        1884                 :            :
        1885                 :            :     /* dump hash stats */
        1886                 :         25 :     _PyHash_Fini();
        1887                 :            :
        1888                 :            : #ifdef Py_TRACE_REFS
        1889                 :            :     /* Display all objects still alive -- this can invoke arbitrary
        1890                 :            :      * __repr__ overrides, so requires a mostly-intact interpreter.
        1891                 :            :      * Alas, a lot of stuff may still be alive now that will be cleaned
        1892                 :            :      * up later.
        1893                 :            :      */
        1894                 :            :
        1895                 :            :     FILE *dump_refs_fp = NULL;
        1896                 :            :     if (dump_refs_file != NULL) {
        1897                 :            :         dump_refs_fp = _Py_wfopen(dump_refs_file, L"w");
        1898                 :            :         if (dump_refs_fp == NULL) {
        1899                 :            :             fprintf(stderr, "PYTHONDUMPREFSFILE: cannot create file: %ls\n", dump_refs_file);
        1900                 :            :         }
        1901                 :            :     }
        1902                 :            :
        1903                 :            :     if (dump_refs) {
        1904                 :            :         _Py_PrintReferences(stderr);
        1905                 :            :     }
        1906                 :            :
        1907                 :            :     if (dump_refs_fp != NULL) {
        1908                 :            :         _Py_PrintReferences(dump_refs_fp);
        1909                 :            :     }
        1910                 :            : #endif /* Py_TRACE_REFS */
        1911                 :            :
        1912                 :            :     /* At this point there's almost no other Python code that will run,
        1913                 :            :        nor interpreter state needed.  The only possibility is the
        1914                 :            :        finalizers of the objects stored on tstate (and tstate->interp),
        1915                 :            :        which are triggered via finalize_interp_clear().
        1916                 :            :
        1917                 :            :        For now we operate as though none of those finalizers actually
        1918                 :            :        need an operational thread state or interpreter.  In reality,
        1919                 :            :        those finalizers may rely on some part of tstate or
        1920                 :            :        tstate->interp, and/or may raise exceptions
        1921                 :            :        or otherwise fail.
        1922                 :            :      */
        1923                 :            :     // XXX Do this sooner during finalization.
        1924                 :            :     // XXX Ensure finalizer errors are handled properly.
        1925                 :            :
        1926                 :         25 :     finalize_interp_clear(tstate);
        1927                 :         25 :     finalize_interp_delete(tstate->interp);
        1928                 :            :
        1929                 :            : #ifdef Py_REF_DEBUG
        1930                 :            :     if (show_ref_count) {
        1931                 :            :         _PyDebug_PrintTotalRefs();
        1932                 :            :     }
        1933                 :            : #endif
        1934                 :            :
        1935                 :            : #ifdef Py_TRACE_REFS
        1936                 :            :     /* Display addresses (& refcnts) of all objects still alive.
        1937                 :            :      * An address can be used to find the repr of the object, printed
        1938                 :            :      * above by _Py_PrintReferences.
        1939                 :            :      */
        1940                 :            :
        1941                 :            :     if (dump_refs) {
        1942                 :            :         _Py_PrintReferenceAddresses(stderr);
        1943                 :            :     }
        1944                 :            :
        1945                 :            :     if (dump_refs_fp != NULL) {
        1946                 :            :         _Py_PrintReferenceAddresses(dump_refs_fp);
        1947                 :            :         fclose(dump_refs_fp);
        1948                 :            :     }
        1949                 :            : #endif /* Py_TRACE_REFS */
        1950                 :            : #ifdef WITH_PYMALLOC
        1951         [ -  + ]:         25 :     if (malloc_stats) {
        1952                 :          0 :         _PyObject_DebugMallocStats(stderr);
        1953                 :            :     }
        1954                 :            : #endif
        1955                 :            :
        1956                 :         25 :     call_ll_exitfuncs(runtime);
        1957                 :            :
        1958                 :         25 :     _PyRuntime_Finalize();
        1959                 :         25 :     return status;
        1960                 :            : }
        1961                 :            :
        1962                 :            : void
        1963                 :          4 : Py_Finalize(void)
        1964                 :            : {
        1965                 :          4 :     Py_FinalizeEx();
        1966                 :          4 : }
        1967                 :            :
        1968                 :            :
        1969                 :            : /* Create and initialize a new interpreter and thread, and return the
        1970                 :            :    new thread.  This requires that Py_Initialize() has been called
        1971                 :            :    first.
        1972                 :            :
        1973                 :            :    Unsuccessful initialization yields a NULL pointer.  Note that *no*
        1974                 :            :    exception information is available even in this case -- the
        1975                 :            :    exception information is held in the thread, and there is no
        1976                 :            :    thread.
        1977                 :            :
        1978                 :            :    Locking: as above.
        1979                 :            :
        1980                 :            : */
        1981                 :            :
        1982                 :            : static PyStatus
        1983                 :          0 : new_interpreter(PyThreadState **tstate_p, const _PyInterpreterConfig *config)
        1984                 :            : {
        1985                 :            :     PyStatus status;
        1986                 :            :
        1987                 :          0 :     status = _PyRuntime_Initialize();
        1988         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        1989                 :          0 :         return status;
        1990                 :            :     }
        1991                 :          0 :     _PyRuntimeState *runtime = &_PyRuntime;
        1992                 :            :
        1993         [ #  # ]:          0 :     if (!runtime->initialized) {
        1994                 :          0 :         return _PyStatus_ERR("Py_Initialize must be called first");
        1995                 :            :     }
        1996                 :            :
        1997                 :            :     /* Issue #10915, #15751: The GIL API doesn't work with multiple
        1998                 :            :        interpreters: disable PyGILState_Check(). */
        1999                 :          0 :     runtime->gilstate.check_enabled = 0;
        2000                 :            :
        2001                 :          0 :     PyInterpreterState *interp = PyInterpreterState_New();
        2002         [ #  # ]:          0 :     if (interp == NULL) {
        2003                 :          0 :         *tstate_p = NULL;
        2004                 :          0 :         return _PyStatus_OK();
        2005                 :            :     }
        2006                 :            :
        2007                 :          0 :     PyThreadState *tstate = _PyThreadState_New(interp);
        2008         [ #  # ]:          0 :     if (tstate == NULL) {
        2009                 :          0 :         PyInterpreterState_Delete(interp);
        2010                 :          0 :         *tstate_p = NULL;
        2011                 :          0 :         return _PyStatus_OK();
        2012                 :            :     }
        2013                 :          0 :     _PyThreadState_Bind(tstate);
        2014                 :            :
        2015                 :          0 :     PyThreadState *save_tstate = PyThreadState_Swap(tstate);
        2016                 :            :
        2017                 :            :     /* Copy the current interpreter config into the new interpreter */
        2018                 :            :     const PyConfig *src_config;
        2019         [ #  # ]:          0 :     if (save_tstate != NULL) {
        2020                 :          0 :         src_config = _PyInterpreterState_GetConfig(save_tstate->interp);
        2021                 :            :     }
        2022                 :            :     else
        2023                 :            :     {
        2024                 :            :         /* No current thread state, copy from the main interpreter */
        2025                 :          0 :         PyInterpreterState *main_interp = _PyInterpreterState_Main();
        2026                 :          0 :         src_config = _PyInterpreterState_GetConfig(main_interp);
        2027                 :            :     }
        2028                 :            :
        2029                 :          0 :     status = _PyConfig_Copy(&interp->config, src_config);
        2030         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        2031                 :          0 :         goto error;
        2032                 :            :     }
        2033                 :            :
        2034                 :          0 :     init_interp_settings(interp, config);
        2035                 :            :
        2036                 :          0 :     status = init_interp_create_gil(tstate);
        2037         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        2038                 :          0 :         goto error;
        2039                 :            :     }
        2040                 :            :
        2041                 :          0 :     status = pycore_interp_init(tstate);
        2042         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        2043                 :          0 :         goto error;
        2044                 :            :     }
        2045                 :            :
        2046                 :          0 :     status = init_interp_main(tstate);
        2047         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        2048                 :          0 :         goto error;
        2049                 :            :     }
        2050                 :            :
        2051                 :          0 :     *tstate_p = tstate;
        2052                 :          0 :     return _PyStatus_OK();
        2053                 :            :
        2054                 :          0 : error:
        2055                 :          0 :     *tstate_p = NULL;
        2056                 :            :
        2057                 :            :     /* Oops, it didn't work.  Undo it all. */
        2058                 :          0 :     PyErr_PrintEx(0);
        2059                 :          0 :     PyThreadState_Clear(tstate);
        2060                 :          0 :     PyThreadState_Delete(tstate);
        2061                 :          0 :     PyInterpreterState_Delete(interp);
        2062                 :          0 :     PyThreadState_Swap(save_tstate);
        2063                 :            :
        2064                 :          0 :     return status;
        2065                 :            : }
        2066                 :            :
        2067                 :            : PyThreadState *
        2068                 :          0 : _Py_NewInterpreterFromConfig(const _PyInterpreterConfig *config)
        2069                 :            : {
        2070                 :          0 :     PyThreadState *tstate = NULL;
        2071                 :          0 :     PyStatus status = new_interpreter(&tstate, config);
        2072         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        2073                 :          0 :         Py_ExitStatusException(status);
        2074                 :            :     }
        2075                 :          0 :     return tstate;
        2076                 :            : }
        2077                 :            :
        2078                 :            : PyThreadState *
        2079                 :          0 : Py_NewInterpreter(void)
        2080                 :            : {
        2081                 :          0 :     const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
        2082                 :          0 :     return _Py_NewInterpreterFromConfig(&config);
        2083                 :            : }
        2084                 :            :
        2085                 :            : /* Delete an interpreter and its last thread.  This requires that the
        2086                 :            :    given thread state is current, that the thread has no remaining
        2087                 :            :    frames, and that it is its interpreter's only remaining thread.
        2088                 :            :    It is a fatal error to violate these constraints.
        2089                 :            :
        2090                 :            :    (Py_FinalizeEx() doesn't have these constraints -- it zaps
        2091                 :            :    everything, regardless.)
        2092                 :            :
        2093                 :            :    Locking: as above.
        2094                 :            :
        2095                 :            : */
        2096                 :            :
        2097                 :            : void
        2098                 :          0 : Py_EndInterpreter(PyThreadState *tstate)
        2099                 :            : {
        2100                 :          0 :     PyInterpreterState *interp = tstate->interp;
        2101                 :            :
        2102         [ #  # ]:          0 :     if (tstate != _PyThreadState_GET()) {
        2103                 :          0 :         Py_FatalError("thread is not current");
        2104                 :            :     }
        2105         [ #  # ]:          0 :     if (tstate->cframe->current_frame != NULL) {
        2106                 :          0 :         Py_FatalError("thread still has a frame");
        2107                 :            :     }
        2108                 :          0 :     interp->finalizing = 1;
        2109                 :            :
        2110                 :            :     // Wrap up existing "threading"-module-created, non-daemon threads.
        2111                 :          0 :     wait_for_thread_shutdown(tstate);
        2112                 :            :
        2113                 :          0 :     _PyAtExit_Call(tstate->interp);
        2114                 :            :
        2115   [ #  #  #  # ]:          0 :     if (tstate != interp->threads.head || tstate->next != NULL) {
        2116                 :          0 :         Py_FatalError("not the last thread");
        2117                 :            :     }
        2118                 :            :
        2119                 :            :     // XXX Call something like _PyImport_Disable() here?
        2120                 :            :
        2121                 :          0 :     _PyImport_FiniExternal(tstate->interp);
        2122                 :          0 :     finalize_modules(tstate);
        2123                 :          0 :     _PyImport_FiniCore(tstate->interp);
        2124                 :            :
        2125                 :          0 :     finalize_interp_clear(tstate);
        2126                 :          0 :     finalize_interp_delete(tstate->interp);
        2127                 :          0 : }
        2128                 :            :
        2129                 :            : /* Add the __main__ module */
        2130                 :            :
        2131                 :            : static PyStatus
        2132                 :         25 : add_main_module(PyInterpreterState *interp)
        2133                 :            : {
        2134                 :            :     PyObject *m, *d, *loader, *ann_dict;
        2135                 :         25 :     m = PyImport_AddModule("__main__");
        2136         [ -  + ]:         25 :     if (m == NULL)
        2137                 :          0 :         return _PyStatus_ERR("can't create __main__ module");
        2138                 :            :
        2139                 :         25 :     d = PyModule_GetDict(m);
        2140                 :         25 :     ann_dict = PyDict_New();
        2141   [ +  -  -  + ]:         50 :     if ((ann_dict == NULL) ||
        2142                 :         25 :         (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) {
        2143                 :          0 :         return _PyStatus_ERR("Failed to initialize __main__.__annotations__");
        2144                 :            :     }
        2145                 :         25 :     Py_DECREF(ann_dict);
        2146                 :            :
        2147         [ +  - ]:         25 :     if (_PyDict_GetItemStringWithError(d, "__builtins__") == NULL) {
        2148         [ -  + ]:         25 :         if (PyErr_Occurred()) {
        2149                 :          0 :             return _PyStatus_ERR("Failed to test __main__.__builtins__");
        2150                 :            :         }
        2151                 :         25 :         PyObject *bimod = PyImport_ImportModule("builtins");
        2152         [ -  + ]:         25 :         if (bimod == NULL) {
        2153                 :          0 :             return _PyStatus_ERR("Failed to retrieve builtins module");
        2154                 :            :         }
        2155         [ -  + ]:         25 :         if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
        2156                 :          0 :             return _PyStatus_ERR("Failed to initialize __main__.__builtins__");
        2157                 :            :         }
        2158                 :         25 :         Py_DECREF(bimod);
        2159                 :            :     }
        2160                 :            :
        2161                 :            :     /* Main is a little special - imp.is_builtin("__main__") will return
        2162                 :            :      * False, but BuiltinImporter is still the most appropriate initial
        2163                 :            :      * setting for its __loader__ attribute. A more suitable value will
        2164                 :            :      * be set if __main__ gets further initialized later in the startup
        2165                 :            :      * process.
        2166                 :            :      */
        2167                 :         25 :     loader = _PyDict_GetItemStringWithError(d, "__loader__");
        2168   [ +  -  +  - ]:         25 :     if (loader == NULL || loader == Py_None) {
        2169         [ -  + ]:         25 :         if (PyErr_Occurred()) {
        2170                 :          0 :             return _PyStatus_ERR("Failed to test __main__.__loader__");
        2171                 :            :         }
        2172                 :         25 :         PyObject *loader = _PyImport_GetImportlibLoader(interp,
        2173                 :            :                                                         "BuiltinImporter");
        2174         [ -  + ]:         25 :         if (loader == NULL) {
        2175                 :          0 :             return _PyStatus_ERR("Failed to retrieve BuiltinImporter");
        2176                 :            :         }
        2177         [ -  + ]:         25 :         if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
        2178                 :          0 :             return _PyStatus_ERR("Failed to initialize __main__.__loader__");
        2179                 :            :         }
        2180                 :         25 :         Py_DECREF(loader);
        2181                 :            :     }
        2182                 :         25 :     return _PyStatus_OK();
        2183                 :            : }
        2184                 :            :
        2185                 :            : /* Import the site module (not into __main__ though) */
        2186                 :            :
        2187                 :            : static PyStatus
        2188                 :         24 : init_import_site(void)
        2189                 :            : {
        2190                 :            :     PyObject *m;
        2191                 :         24 :     m = PyImport_ImportModule("site");
        2192         [ -  + ]:         24 :     if (m == NULL) {
        2193                 :          0 :         return _PyStatus_ERR("Failed to import the site module");
        2194                 :            :     }
        2195                 :         24 :     Py_DECREF(m);
        2196                 :         24 :     return _PyStatus_OK();
        2197                 :            : }
        2198                 :            :
        2199                 :            : /* Check if a file descriptor is valid or not.
        2200                 :            :    Return 0 if the file descriptor is invalid, return non-zero otherwise. */
        2201                 :            : static int
        2202                 :         75 : is_valid_fd(int fd)
        2203                 :            : {
        2204                 :            : /* dup() is faster than fstat(): fstat() can require input/output operations,
        2205                 :            :    whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python
        2206                 :            :    startup. Problem: dup() doesn't check if the file descriptor is valid on
        2207                 :            :    some platforms.
        2208                 :            :
        2209                 :            :    fcntl(fd, F_GETFD) is even faster, because it only checks the process table.
        2210                 :            :    It is preferred over dup() when available, since it cannot fail with the
        2211                 :            :    "too many open files" error (EMFILE).
        2212                 :            :
        2213                 :            :    bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other
        2214                 :            :    side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with
        2215                 :            :    EBADF. FreeBSD has similar issue (bpo-32849).
        2216                 :            :
        2217                 :            :    Only use dup() on Linux where dup() is enough to detect invalid FD
        2218                 :            :    (bpo-32849).
        2219                 :            : */
        2220         [ -  + ]:         75 :     if (fd < 0) {
        2221                 :          0 :         return 0;
        2222                 :            :     }
        2223                 :            : #if defined(F_GETFD) && ( \
        2224                 :            :         defined(__linux__) || \
        2225                 :            :         defined(__APPLE__) || \
        2226                 :            :         defined(__wasm__))
        2227                 :         75 :     return fcntl(fd, F_GETFD) >= 0;
        2228                 :            : #elif defined(__linux__)
        2229                 :            :     int fd2 = dup(fd);
        2230                 :            :     if (fd2 >= 0) {
        2231                 :            :         close(fd2);
        2232                 :            :     }
        2233                 :            :     return (fd2 >= 0);
        2234                 :            : #elif defined(MS_WINDOWS)
        2235                 :            :     HANDLE hfile;
        2236                 :            :     _Py_BEGIN_SUPPRESS_IPH
        2237                 :            :     hfile = (HANDLE)_get_osfhandle(fd);
        2238                 :            :     _Py_END_SUPPRESS_IPH
        2239                 :            :     return (hfile != INVALID_HANDLE_VALUE
        2240                 :            :             && GetFileType(hfile) != FILE_TYPE_UNKNOWN);
        2241                 :            : #else
        2242                 :            :     struct stat st;
        2243                 :            :     return (fstat(fd, &st) == 0);
        2244                 :            : #endif
        2245                 :            : }
        2246                 :            :
        2247                 :            : /* returns Py_None if the fd is not valid */
        2248                 :            : static PyObject*
        2249                 :         75 : create_stdio(const PyConfig *config, PyObject* io,
        2250                 :            :     int fd, int write_mode, const char* name,
        2251                 :            :     const wchar_t* encoding, const wchar_t* errors)
        2252                 :            : {
        2253                 :         75 :     PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
        2254                 :            :     const char* mode;
        2255                 :            :     const char* newline;
        2256                 :            :     PyObject *line_buffering, *write_through;
        2257                 :            :     int buffering, isatty;
        2258                 :         75 :     const int buffered_stdio = config->buffered_stdio;
        2259                 :            :
        2260         [ -  + ]:         75 :     if (!is_valid_fd(fd))
        2261                 :          0 :         Py_RETURN_NONE;
        2262                 :            :
        2263                 :            :     /* stdin is always opened in buffered mode, first because it shouldn't
        2264                 :            :        make a difference in common use cases, second because TextIOWrapper
        2265                 :            :        depends on the presence of a read1() method which only exists on
        2266                 :            :        buffered streams.
        2267                 :            :     */
        2268   [ -  +  -  - ]:         75 :     if (!buffered_stdio && write_mode)
        2269                 :          0 :         buffering = 0;
        2270                 :            :     else
        2271                 :         75 :         buffering = -1;
        2272         [ +  + ]:         75 :     if (write_mode)
        2273                 :         50 :         mode = "wb";
        2274                 :            :     else
        2275                 :         25 :         mode = "rb";
        2276                 :         75 :     buf = _PyObject_CallMethod(io, &_Py_ID(open), "isiOOOO",
        2277                 :            :                                fd, mode, buffering,
        2278                 :            :                                Py_None, Py_None, /* encoding, errors */
        2279                 :            :                                Py_None, Py_False); /* newline, closefd */
        2280         [ -  + ]:         75 :     if (buf == NULL)
        2281                 :          0 :         goto error;
        2282                 :            :
        2283         [ +  - ]:         75 :     if (buffering) {
        2284                 :         75 :         raw = PyObject_GetAttr(buf, &_Py_ID(raw));
        2285         [ -  + ]:         75 :         if (raw == NULL)
        2286                 :          0 :             goto error;
        2287                 :            :     }
        2288                 :            :     else {
        2289                 :          0 :         raw = Py_NewRef(buf);
        2290                 :            :     }
        2291                 :            :
        2292                 :            : #ifdef HAVE_WINDOWS_CONSOLE_IO
        2293                 :            :     /* Windows console IO is always UTF-8 encoded */
        2294                 :            :     PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr(
        2295                 :            :             &_Py_ID(_io), &_Py_ID(_WindowsConsoleIO));
        2296                 :            :     if (winconsoleio_type == NULL) {
        2297                 :            :         goto error;
        2298                 :            :     }
        2299                 :            :     int is_subclass = PyObject_TypeCheck(raw, winconsoleio_type);
        2300                 :            :     Py_DECREF(winconsoleio_type);
        2301                 :            :     if (is_subclass) {
        2302                 :            :         encoding = L"utf-8";
        2303                 :            :     }
        2304                 :            : #endif
        2305                 :            :
        2306                 :         75 :     text = PyUnicode_FromString(name);
        2307   [ +  -  -  + ]:         75 :     if (text == NULL || PyObject_SetAttr(raw, &_Py_ID(name), text) < 0)
        2308                 :          0 :         goto error;
        2309                 :         75 :     res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty));
        2310         [ -  + ]:         75 :     if (res == NULL)
        2311                 :          0 :         goto error;
        2312                 :         75 :     isatty = PyObject_IsTrue(res);
        2313                 :         75 :     Py_DECREF(res);
        2314         [ -  + ]:         75 :     if (isatty == -1)
        2315                 :          0 :         goto error;
        2316         [ -  + ]:         75 :     if (!buffered_stdio)
        2317                 :          0 :         write_through = Py_True;
        2318                 :            :     else
        2319                 :         75 :         write_through = Py_False;
        2320   [ +  -  +  +  :         75 :     if (buffered_stdio && (isatty || fd == fileno(stderr)))
                       -  + ]
        2321                 :         74 :         line_buffering = Py_True;
        2322                 :            :     else
        2323                 :          1 :         line_buffering = Py_False;
        2324                 :            :
        2325         [ +  - ]:         75 :     Py_CLEAR(raw);
        2326         [ +  - ]:         75 :     Py_CLEAR(text);
        2327                 :            :
        2328                 :            : #ifdef MS_WINDOWS
        2329                 :            :     /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r"
        2330                 :            :        newlines to "\n".
        2331                 :            :        sys.stdout and sys.stderr: translate "\n" to "\r\n". */
        2332                 :            :     newline = NULL;
        2333                 :            : #else
        2334                 :            :     /* sys.stdin: split lines at "\n".
        2335                 :            :        sys.stdout and sys.stderr: don't translate newlines (use "\n"). */
        2336                 :         75 :     newline = "\n";
        2337                 :            : #endif
        2338                 :            :
        2339                 :         75 :     PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1);
        2340         [ -  + ]:         75 :     if (encoding_str == NULL) {
        2341         [ #  # ]:          0 :         Py_CLEAR(buf);
        2342                 :          0 :         goto error;
        2343                 :            :     }
        2344                 :            :
        2345                 :         75 :     PyObject *errors_str = PyUnicode_FromWideChar(errors, -1);
        2346         [ -  + ]:         75 :     if (errors_str == NULL) {
        2347         [ #  # ]:          0 :         Py_CLEAR(buf);
        2348         [ #  # ]:          0 :         Py_CLEAR(encoding_str);
        2349                 :          0 :         goto error;
        2350                 :            :     }
        2351                 :            :
        2352                 :         75 :     stream = _PyObject_CallMethod(io, &_Py_ID(TextIOWrapper), "OOOsOO",
        2353                 :            :                                   buf, encoding_str, errors_str,
        2354                 :            :                                   newline, line_buffering, write_through);
        2355         [ +  - ]:         75 :     Py_CLEAR(buf);
        2356         [ +  - ]:         75 :     Py_CLEAR(encoding_str);
        2357         [ +  - ]:         75 :     Py_CLEAR(errors_str);
        2358         [ -  + ]:         75 :     if (stream == NULL)
        2359                 :          0 :         goto error;
        2360                 :            :
        2361         [ +  + ]:         75 :     if (write_mode)
        2362                 :         50 :         mode = "w";
        2363                 :            :     else
        2364                 :         25 :         mode = "r";
        2365                 :         75 :     text = PyUnicode_FromString(mode);
        2366   [ +  -  -  + ]:         75 :     if (!text || PyObject_SetAttr(stream, &_Py_ID(mode), text) < 0)
        2367                 :          0 :         goto error;
        2368         [ +  - ]:         75 :     Py_CLEAR(text);
        2369                 :         75 :     return stream;
        2370                 :            :
        2371                 :          0 : error:
        2372                 :          0 :     Py_XDECREF(buf);
        2373                 :          0 :     Py_XDECREF(stream);
        2374                 :          0 :     Py_XDECREF(text);
        2375                 :          0 :     Py_XDECREF(raw);
        2376                 :            :
        2377   [ #  #  #  # ]:          0 :     if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) {
        2378                 :            :         /* Issue #24891: the file descriptor was closed after the first
        2379                 :            :            is_valid_fd() check was called. Ignore the OSError and set the
        2380                 :            :            stream to None. */
        2381                 :          0 :         PyErr_Clear();
        2382                 :          0 :         Py_RETURN_NONE;
        2383                 :            :     }
        2384                 :          0 :     return NULL;
        2385                 :            : }
        2386                 :            :
        2387                 :            : /* Set builtins.open to io.open */
        2388                 :            : static PyStatus
        2389                 :         25 : init_set_builtins_open(void)
        2390                 :            : {
        2391                 :            :     PyObject *wrapper;
        2392                 :         25 :     PyObject *bimod = NULL;
        2393                 :         25 :     PyStatus res = _PyStatus_OK();
        2394                 :            :
        2395         [ -  + ]:         25 :     if (!(bimod = PyImport_ImportModule("builtins"))) {
        2396                 :          0 :         goto error;
        2397                 :            :     }
        2398                 :            :
        2399         [ -  + ]:         25 :     if (!(wrapper = _PyImport_GetModuleAttrString("io", "open"))) {
        2400                 :          0 :         goto error;
        2401                 :            :     }
        2402                 :            :
        2403                 :            :     /* Set builtins.open */
        2404         [ -  + ]:         25 :     if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
        2405                 :          0 :         Py_DECREF(wrapper);
        2406                 :          0 :         goto error;
        2407                 :            :     }
        2408                 :         25 :     Py_DECREF(wrapper);
        2409                 :         25 :     goto done;
        2410                 :            :
        2411                 :          0 : error:
        2412                 :          0 :     res = _PyStatus_ERR("can't initialize io.open");
        2413                 :            :
        2414                 :         25 : done:
        2415                 :         25 :     Py_XDECREF(bimod);
        2416                 :         25 :     return res;
        2417                 :            : }
        2418                 :            :
        2419                 :            :
        2420                 :            : /* Create sys.stdin, sys.stdout and sys.stderr */
        2421                 :            : static PyStatus
        2422                 :         25 : init_sys_streams(PyThreadState *tstate)
        2423                 :            : {
        2424                 :         25 :     PyObject *iomod = NULL;
        2425                 :         25 :     PyObject *std = NULL;
        2426                 :            :     int fd;
        2427                 :            :     PyObject * encoding_attr;
        2428                 :         25 :     PyStatus res = _PyStatus_OK();
        2429                 :         25 :     const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
        2430                 :            :
        2431                 :            :     /* Check that stdin is not a directory
        2432                 :            :        Using shell redirection, you can redirect stdin to a directory,
        2433                 :            :        crashing the Python interpreter. Catch this common mistake here
        2434                 :            :        and output a useful error message. Note that under MS Windows,
        2435                 :            :        the shell already prevents that. */
        2436                 :            : #ifndef MS_WINDOWS
        2437                 :            :     struct _Py_stat_struct sb;
        2438         [ +  - ]:         25 :     if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 &&
        2439         [ -  + ]:         25 :         S_ISDIR(sb.st_mode)) {
        2440                 :          0 :         return _PyStatus_ERR("<stdin> is a directory, cannot continue");
        2441                 :            :     }
        2442                 :            : #endif
        2443                 :            :
        2444         [ -  + ]:         25 :     if (!(iomod = PyImport_ImportModule("io"))) {
        2445                 :          0 :         goto error;
        2446                 :            :     }
        2447                 :            :
        2448                 :            :     /* Set sys.stdin */
        2449                 :         25 :     fd = fileno(stdin);
        2450                 :            :     /* Under some conditions stdin, stdout and stderr may not be connected
        2451                 :            :      * and fileno() may point to an invalid file descriptor. For example
        2452                 :            :      * GUI apps don't have valid standard streams by default.
        2453                 :            :      */
        2454                 :         25 :     std = create_stdio(config, iomod, fd, 0, "<stdin>",
        2455                 :         25 :                        config->stdio_encoding,
        2456                 :         25 :                        config->stdio_errors);
        2457         [ -  + ]:         25 :     if (std == NULL)
        2458                 :          0 :         goto error;
        2459                 :         25 :     PySys_SetObject("__stdin__", std);
        2460                 :         25 :     _PySys_SetAttr(&_Py_ID(stdin), std);
        2461                 :         25 :     Py_DECREF(std);
        2462                 :            :
        2463                 :            :     /* Set sys.stdout */
        2464                 :         25 :     fd = fileno(stdout);
        2465                 :         25 :     std = create_stdio(config, iomod, fd, 1, "<stdout>",
        2466                 :         25 :                        config->stdio_encoding,
        2467                 :         25 :                        config->stdio_errors);
        2468         [ -  + ]:         25 :     if (std == NULL)
        2469                 :          0 :         goto error;
        2470                 :         25 :     PySys_SetObject("__stdout__", std);
        2471                 :         25 :     _PySys_SetAttr(&_Py_ID(stdout), std);
        2472                 :         25 :     Py_DECREF(std);
        2473                 :            :
        2474                 :            : #if 1 /* Disable this if you have trouble debugging bootstrap stuff */
        2475                 :            :     /* Set sys.stderr, replaces the preliminary stderr */
        2476                 :         25 :     fd = fileno(stderr);
        2477                 :         25 :     std = create_stdio(config, iomod, fd, 1, "<stderr>",
        2478                 :         25 :                        config->stdio_encoding,
        2479                 :            :                        L"backslashreplace");
        2480         [ -  + ]:         25 :     if (std == NULL)
        2481                 :          0 :         goto error;
        2482                 :            :
        2483                 :            :     /* Same as hack above, pre-import stderr's codec to avoid recursion
        2484                 :            :        when import.c tries to write to stderr in verbose mode. */
        2485                 :         25 :     encoding_attr = PyObject_GetAttrString(std, "encoding");
        2486         [ +  - ]:         25 :     if (encoding_attr != NULL) {
        2487                 :         25 :         const char *std_encoding = PyUnicode_AsUTF8(encoding_attr);
        2488         [ +  - ]:         25 :         if (std_encoding != NULL) {
        2489                 :         25 :             PyObject *codec_info = _PyCodec_Lookup(std_encoding);
        2490                 :         25 :             Py_XDECREF(codec_info);
        2491                 :            :         }
        2492                 :         25 :         Py_DECREF(encoding_attr);
        2493                 :            :     }
        2494                 :         25 :     _PyErr_Clear(tstate);  /* Not a fatal error if codec isn't available */
        2495                 :            :
        2496         [ -  + ]:         25 :     if (PySys_SetObject("__stderr__", std) < 0) {
        2497                 :          0 :         Py_DECREF(std);
        2498                 :          0 :         goto error;
        2499                 :            :     }
        2500         [ -  + ]:         25 :     if (_PySys_SetAttr(&_Py_ID(stderr), std) < 0) {
        2501                 :          0 :         Py_DECREF(std);
        2502                 :          0 :         goto error;
        2503                 :            :     }
        2504                 :         25 :     Py_DECREF(std);
        2505                 :            : #endif
        2506                 :            :
        2507                 :         25 :     goto done;
        2508                 :            :
        2509                 :          0 : error:
        2510                 :          0 :     res = _PyStatus_ERR("can't initialize sys standard streams");
        2511                 :            :
        2512                 :         25 : done:
        2513                 :         25 :     _Py_ClearStandardStreamEncoding();
        2514                 :         25 :     Py_XDECREF(iomod);
        2515                 :         25 :     return res;
        2516                 :            : }
        2517                 :            :
        2518                 :            :
        2519                 :            : static void
        2520                 :          0 : _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp,
        2521                 :            :                               PyThreadState *tstate)
        2522                 :            : {
        2523                 :          0 :     PUTS(fd, "\n");
        2524                 :            :
        2525                 :            :     /* display the current Python stack */
        2526                 :          0 :     _Py_DumpTracebackThreads(fd, interp, tstate);
        2527                 :          0 : }
        2528                 :            :
        2529                 :            : /* Print the current exception (if an exception is set) with its traceback,
        2530                 :            :    or display the current Python stack.
        2531                 :            :
        2532                 :            :    Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
        2533                 :            :    called on catastrophic cases.
        2534                 :            :
        2535                 :            :    Return 1 if the traceback was displayed, 0 otherwise. */
        2536                 :            :
        2537                 :            : static int
        2538                 :          0 : _Py_FatalError_PrintExc(PyThreadState *tstate)
        2539                 :            : {
        2540                 :          0 :     PyObject *exc = _PyErr_GetRaisedException(tstate);
        2541         [ #  # ]:          0 :     if (exc == NULL) {
        2542                 :            :         /* No current exception */
        2543                 :          0 :         return 0;
        2544                 :            :     }
        2545                 :            :
        2546                 :          0 :     PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
        2547   [ #  #  #  # ]:          0 :     if (ferr == NULL || ferr == Py_None) {
        2548                 :            :         /* sys.stderr is not set yet or set to None,
        2549                 :            :            no need to try to display the exception */
        2550                 :          0 :         Py_DECREF(exc);
        2551                 :          0 :         return 0;
        2552                 :            :     }
        2553                 :            :
        2554                 :          0 :     PyErr_DisplayException(exc);
        2555                 :            :
        2556                 :          0 :     PyObject *tb = PyException_GetTraceback(exc);
        2557   [ #  #  #  # ]:          0 :     int has_tb = (tb != NULL) && (tb != Py_None);
        2558                 :          0 :     Py_XDECREF(tb);
        2559                 :          0 :     Py_DECREF(exc);
        2560                 :            :
        2561                 :            :     /* sys.stderr may be buffered: call sys.stderr.flush() */
        2562                 :          0 :     PyObject *res = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush));
        2563         [ #  # ]:          0 :     if (res == NULL) {
        2564                 :          0 :         _PyErr_Clear(tstate);
        2565                 :            :     }
        2566                 :            :     else {
        2567                 :          0 :         Py_DECREF(res);
        2568                 :            :     }
        2569                 :            :
        2570                 :          0 :     return has_tb;
        2571                 :            : }
        2572                 :            :
        2573                 :            : /* Print fatal error message and abort */
        2574                 :            :
        2575                 :            : #ifdef MS_WINDOWS
        2576                 :            : static void
        2577                 :            : fatal_output_debug(const char *msg)
        2578                 :            : {
        2579                 :            :     /* buffer of 256 bytes allocated on the stack */
        2580                 :            :     WCHAR buffer[256 / sizeof(WCHAR)];
        2581                 :            :     size_t buflen = Py_ARRAY_LENGTH(buffer) - 1;
        2582                 :            :     size_t msglen;
        2583                 :            :
        2584                 :            :     OutputDebugStringW(L"Fatal Python error: ");
        2585                 :            :
        2586                 :            :     msglen = strlen(msg);
        2587                 :            :     while (msglen) {
        2588                 :            :         size_t i;
        2589                 :            :
        2590                 :            :         if (buflen > msglen) {
        2591                 :            :             buflen = msglen;
        2592                 :            :         }
        2593                 :            :
        2594                 :            :         /* Convert the message to wchar_t. This uses a simple one-to-one
        2595                 :            :            conversion, assuming that the this error message actually uses
        2596                 :            :            ASCII only. If this ceases to be true, we will have to convert. */
        2597                 :            :         for (i=0; i < buflen; ++i) {
        2598                 :            :             buffer[i] = msg[i];
        2599                 :            :         }
        2600                 :            :         buffer[i] = L'\0';
        2601                 :            :         OutputDebugStringW(buffer);
        2602                 :            :
        2603                 :            :         msg += buflen;
        2604                 :            :         msglen -= buflen;
        2605                 :            :     }
        2606                 :            :     OutputDebugStringW(L"\n");
        2607                 :            : }
        2608                 :            : #endif
        2609                 :            :
        2610                 :            :
        2611                 :            : static void
        2612                 :          0 : fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime)
        2613                 :            : {
        2614                 :          0 :     PUTS(fd, "Python runtime state: ");
        2615                 :          0 :     PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
        2616         [ #  # ]:          0 :     if (finalizing) {
        2617                 :          0 :         PUTS(fd, "finalizing (tstate=0x");
        2618                 :          0 :         _Py_DumpHexadecimal(fd, (uintptr_t)finalizing, sizeof(finalizing) * 2);
        2619                 :          0 :         PUTS(fd, ")");
        2620                 :            :     }
        2621         [ #  # ]:          0 :     else if (runtime->initialized) {
        2622                 :          0 :         PUTS(fd, "initialized");
        2623                 :            :     }
        2624         [ #  # ]:          0 :     else if (runtime->core_initialized) {
        2625                 :          0 :         PUTS(fd, "core initialized");
        2626                 :            :     }
        2627         [ #  # ]:          0 :     else if (runtime->preinitialized) {
        2628                 :          0 :         PUTS(fd, "preinitialized");
        2629                 :            :     }
        2630         [ #  # ]:          0 :     else if (runtime->preinitializing) {
        2631                 :          0 :         PUTS(fd, "preinitializing");
        2632                 :            :     }
        2633                 :            :     else {
        2634                 :          0 :         PUTS(fd, "unknown");
        2635                 :            :     }
        2636                 :          0 :     PUTS(fd, "\n");
        2637                 :          0 : }
        2638                 :            :
        2639                 :            :
        2640                 :            : static inline void _Py_NO_RETURN
        2641                 :          0 : fatal_error_exit(int status)
        2642                 :            : {
        2643         [ #  # ]:          0 :     if (status < 0) {
        2644                 :            : #if defined(MS_WINDOWS) && defined(_DEBUG)
        2645                 :            :         DebugBreak();
        2646                 :            : #endif
        2647                 :          0 :         abort();
        2648                 :            :     }
        2649                 :            :     else {
        2650                 :          0 :         exit(status);
        2651                 :            :     }
        2652                 :            : }
        2653                 :            :
        2654                 :            :
        2655                 :            : // Dump the list of extension modules of sys.modules, excluding stdlib modules
        2656                 :            : // (sys.stdlib_module_names), into fd file descriptor.
        2657                 :            : //
        2658                 :            : // This function is called by a signal handler in faulthandler: avoid memory
        2659                 :            : // allocations and keep the implementation simple. For example, the list is not
        2660                 :            : // sorted on purpose.
        2661                 :            : void
        2662                 :          0 : _Py_DumpExtensionModules(int fd, PyInterpreterState *interp)
        2663                 :            : {
        2664         [ #  # ]:          0 :     if (interp == NULL) {
        2665                 :          0 :         return;
        2666                 :            :     }
        2667                 :          0 :     PyObject *modules = _PyImport_GetModules(interp);
        2668   [ #  #  #  # ]:          0 :     if (modules == NULL || !PyDict_Check(modules)) {
        2669                 :          0 :         return;
        2670                 :            :     }
        2671                 :            :
        2672                 :            :     Py_ssize_t pos;
        2673                 :            :     PyObject *key, *value;
        2674                 :            :
        2675                 :            :     // Avoid PyDict_GetItemString() which calls PyUnicode_FromString(),
        2676                 :            :     // memory cannot be allocated on the heap in a signal handler.
        2677                 :            :     // Iterate on the dict instead.
        2678                 :          0 :     PyObject *stdlib_module_names = NULL;
        2679         [ #  # ]:          0 :     if (interp->sysdict != NULL) {
        2680                 :          0 :         pos = 0;
        2681         [ #  # ]:          0 :         while (PyDict_Next(interp->sysdict, &pos, &key, &value)) {
        2682         [ #  # ]:          0 :             if (PyUnicode_Check(key)
        2683         [ #  # ]:          0 :                && PyUnicode_CompareWithASCIIString(key, "stdlib_module_names") == 0) {
        2684                 :          0 :                 stdlib_module_names = value;
        2685                 :          0 :                 break;
        2686                 :            :             }
        2687                 :            :         }
        2688                 :            :     }
        2689                 :            :     // If we failed to get sys.stdlib_module_names or it's not a frozenset,
        2690                 :            :     // don't exclude stdlib modules.
        2691   [ #  #  #  #  :          0 :     if (stdlib_module_names != NULL && !PyFrozenSet_Check(stdlib_module_names)) {
                       #  # ]
        2692                 :          0 :         stdlib_module_names = NULL;
        2693                 :            :     }
        2694                 :            :
        2695                 :            :     // List extensions
        2696                 :          0 :     int header = 1;
        2697                 :          0 :     Py_ssize_t count = 0;
        2698                 :          0 :     pos = 0;
        2699         [ #  # ]:          0 :     while (PyDict_Next(modules, &pos, &key, &value)) {
        2700         [ #  # ]:          0 :         if (!PyUnicode_Check(key)) {
        2701                 :          0 :             continue;
        2702                 :            :         }
        2703         [ #  # ]:          0 :         if (!_PyModule_IsExtension(value)) {
        2704                 :          0 :             continue;
        2705                 :            :         }
        2706                 :            :         // Use the module name from the sys.modules key,
        2707                 :            :         // don't attempt to get the module object name.
        2708         [ #  # ]:          0 :         if (stdlib_module_names != NULL) {
        2709                 :          0 :             int is_stdlib_ext = 0;
        2710                 :            :
        2711                 :          0 :             Py_ssize_t i = 0;
        2712                 :            :             PyObject *item;
        2713                 :            :             Py_hash_t hash;
        2714         [ #  # ]:          0 :             while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) {
        2715         [ #  # ]:          0 :                 if (PyUnicode_Check(item)
        2716         [ #  # ]:          0 :                     && PyUnicode_Compare(key, item) == 0)
        2717                 :            :                 {
        2718                 :          0 :                     is_stdlib_ext = 1;
        2719                 :          0 :                     break;
        2720                 :            :                 }
        2721                 :            :             }
        2722         [ #  # ]:          0 :             if (is_stdlib_ext) {
        2723                 :            :                 // Ignore stdlib extension
        2724                 :          0 :                 continue;
        2725                 :            :             }
        2726                 :            :         }
        2727                 :            :
        2728         [ #  # ]:          0 :         if (header) {
        2729                 :          0 :             PUTS(fd, "\nExtension modules: ");
        2730                 :          0 :             header = 0;
        2731                 :            :         }
        2732                 :            :         else {
        2733                 :          0 :             PUTS(fd, ", ");
        2734                 :            :         }
        2735                 :            :
        2736                 :          0 :         _Py_DumpASCII(fd, key);
        2737                 :          0 :         count++;
        2738                 :            :     }
        2739                 :            :
        2740         [ #  # ]:          0 :     if (count) {
        2741                 :          0 :         PUTS(fd, " (total: ");
        2742                 :          0 :         _Py_DumpDecimal(fd, count);
        2743                 :          0 :         PUTS(fd, ")");
        2744                 :          0 :         PUTS(fd, "\n");
        2745                 :            :     }
        2746                 :            : }
        2747                 :            :
        2748                 :            :
        2749                 :            : static void _Py_NO_RETURN
        2750                 :          0 : fatal_error(int fd, int header, const char *prefix, const char *msg,
        2751                 :            :             int status)
        2752                 :            : {
        2753                 :            :     static int reentrant = 0;
        2754                 :            :
        2755         [ #  # ]:          0 :     if (reentrant) {
        2756                 :            :         /* Py_FatalError() caused a second fatal error.
        2757                 :            :            Example: flush_std_files() raises a recursion error. */
        2758                 :          0 :         fatal_error_exit(status);
        2759                 :            :     }
        2760                 :          0 :     reentrant = 1;
        2761                 :            :
        2762         [ #  # ]:          0 :     if (header) {
        2763                 :          0 :         PUTS(fd, "Fatal Python error: ");
        2764         [ #  # ]:          0 :         if (prefix) {
        2765                 :          0 :             PUTS(fd, prefix);
        2766                 :          0 :             PUTS(fd, ": ");
        2767                 :            :         }
        2768         [ #  # ]:          0 :         if (msg) {
        2769                 :          0 :             PUTS(fd, msg);
        2770                 :            :         }
        2771                 :            :         else {
        2772                 :          0 :             PUTS(fd, "<message not set>");
        2773                 :            :         }
        2774                 :          0 :         PUTS(fd, "\n");
        2775                 :            :     }
        2776                 :            :
        2777                 :          0 :     _PyRuntimeState *runtime = &_PyRuntime;
        2778                 :          0 :     fatal_error_dump_runtime(fd, runtime);
        2779                 :            :
        2780                 :            :     /* Check if the current thread has a Python thread state
        2781                 :            :        and holds the GIL.
        2782                 :            :
        2783                 :            :        tss_tstate is NULL if Py_FatalError() is called from a C thread which
        2784                 :            :        has no Python thread state.
        2785                 :            :
        2786                 :            :        tss_tstate != tstate if the current Python thread does not hold the GIL.
        2787                 :            :        */
        2788                 :          0 :     PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
        2789                 :          0 :     PyInterpreterState *interp = NULL;
        2790                 :          0 :     PyThreadState *tss_tstate = PyGILState_GetThisThreadState();
        2791         [ #  # ]:          0 :     if (tstate != NULL) {
        2792                 :          0 :         interp = tstate->interp;
        2793                 :            :     }
        2794         [ #  # ]:          0 :     else if (tss_tstate != NULL) {
        2795                 :          0 :         interp = tss_tstate->interp;
        2796                 :            :     }
        2797   [ #  #  #  # ]:          0 :     int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate);
        2798                 :            :
        2799         [ #  # ]:          0 :     if (has_tstate_and_gil) {
        2800                 :            :         /* If an exception is set, print the exception with its traceback */
        2801         [ #  # ]:          0 :         if (!_Py_FatalError_PrintExc(tss_tstate)) {
        2802                 :            :             /* No exception is set, or an exception is set without traceback */
        2803                 :          0 :             _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
        2804                 :            :         }
        2805                 :            :     }
        2806                 :            :     else {
        2807                 :          0 :         _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
        2808                 :            :     }
        2809                 :            :
        2810                 :          0 :     _Py_DumpExtensionModules(fd, interp);
        2811                 :            :
        2812                 :            :     /* The main purpose of faulthandler is to display the traceback.
        2813                 :            :        This function already did its best to display a traceback.
        2814                 :            :        Disable faulthandler to prevent writing a second traceback
        2815                 :            :        on abort(). */
        2816                 :          0 :     _PyFaulthandler_Fini();
        2817                 :            :
        2818                 :            :     /* Check if the current Python thread hold the GIL */
        2819         [ #  # ]:          0 :     if (has_tstate_and_gil) {
        2820                 :            :         /* Flush sys.stdout and sys.stderr */
        2821                 :          0 :         flush_std_files();
        2822                 :            :     }
        2823                 :            :
        2824                 :            : #ifdef MS_WINDOWS
        2825                 :            :     fatal_output_debug(msg);
        2826                 :            : #endif /* MS_WINDOWS */
        2827                 :            :
        2828                 :          0 :     fatal_error_exit(status);
        2829                 :            : }
        2830                 :            :
        2831                 :            :
        2832                 :            : #undef Py_FatalError
        2833                 :            :
        2834                 :            : void _Py_NO_RETURN
        2835                 :          0 : Py_FatalError(const char *msg)
        2836                 :            : {
        2837                 :          0 :     fatal_error(fileno(stderr), 1, NULL, msg, -1);
        2838                 :            : }
        2839                 :            :
        2840                 :            :
        2841                 :            : void _Py_NO_RETURN
        2842                 :          0 : _Py_FatalErrorFunc(const char *func, const char *msg)
        2843                 :            : {
        2844                 :          0 :     fatal_error(fileno(stderr), 1, func, msg, -1);
        2845                 :            : }
        2846                 :            :
        2847                 :            :
        2848                 :            : void _Py_NO_RETURN
        2849                 :          0 : _Py_FatalErrorFormat(const char *func, const char *format, ...)
        2850                 :            : {
        2851                 :            :     static int reentrant = 0;
        2852         [ #  # ]:          0 :     if (reentrant) {
        2853                 :            :         /* _Py_FatalErrorFormat() caused a second fatal error */
        2854                 :          0 :         fatal_error_exit(-1);
        2855                 :            :     }
        2856                 :          0 :     reentrant = 1;
        2857                 :            :
        2858                 :          0 :     FILE *stream = stderr;
        2859                 :          0 :     const int fd = fileno(stream);
        2860                 :          0 :     PUTS(fd, "Fatal Python error: ");
        2861         [ #  # ]:          0 :     if (func) {
        2862                 :          0 :         PUTS(fd, func);
        2863                 :          0 :         PUTS(fd, ": ");
        2864                 :            :     }
        2865                 :            :
        2866                 :            :     va_list vargs;
        2867                 :          0 :     va_start(vargs, format);
        2868                 :          0 :     vfprintf(stream, format, vargs);
        2869                 :          0 :     va_end(vargs);
        2870                 :            :
        2871                 :          0 :     fputs("\n", stream);
        2872                 :          0 :     fflush(stream);
        2873                 :            :
        2874                 :          0 :     fatal_error(fd, 0, NULL, NULL, -1);
        2875                 :            : }
        2876                 :            :
        2877                 :            :
        2878                 :            : void _Py_NO_RETURN
        2879                 :          0 : _Py_FatalRefcountErrorFunc(const char *func, const char *msg)
        2880                 :            : {
        2881                 :          0 :     _Py_FatalErrorFormat(func,
        2882                 :            :                          "%s: bug likely caused by a refcount error "
        2883                 :            :                          "in a C extension",
        2884                 :            :                          msg);
        2885                 :            : }
        2886                 :            :
        2887                 :            :
        2888                 :            : void _Py_NO_RETURN
        2889                 :          0 : Py_ExitStatusException(PyStatus status)
        2890                 :            : {
        2891         [ #  # ]:          0 :     if (_PyStatus_IS_EXIT(status)) {
        2892                 :          0 :         exit(status.exitcode);
        2893                 :            :     }
        2894         [ #  # ]:          0 :     else if (_PyStatus_IS_ERROR(status)) {
        2895                 :          0 :         fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1);
        2896                 :            :     }
        2897                 :            :     else {
        2898                 :          0 :         Py_FatalError("Py_ExitStatusException() must not be called on success");
        2899                 :            :     }
        2900                 :            : }
        2901                 :            :
        2902                 :            :
        2903                 :            : /* Wait until threading._shutdown completes, provided
        2904                 :            :    the threading module was imported in the first place.
        2905                 :            :    The shutdown routine will wait until all non-daemon
        2906                 :            :    "threading" threads have completed. */
        2907                 :            : static void
        2908                 :         25 : wait_for_thread_shutdown(PyThreadState *tstate)
        2909                 :            : {
        2910                 :            :     PyObject *result;
        2911                 :         25 :     PyObject *threading = PyImport_GetModule(&_Py_ID(threading));
        2912         [ +  + ]:         25 :     if (threading == NULL) {
        2913         [ -  + ]:         21 :         if (_PyErr_Occurred(tstate)) {
        2914                 :          0 :             PyErr_WriteUnraisable(NULL);
        2915                 :            :         }
        2916                 :            :         /* else: threading not imported */
        2917                 :         21 :         return;
        2918                 :            :     }
        2919                 :          4 :     result = PyObject_CallMethodNoArgs(threading, &_Py_ID(_shutdown));
        2920         [ -  + ]:          4 :     if (result == NULL) {
        2921                 :          0 :         PyErr_WriteUnraisable(threading);
        2922                 :            :     }
        2923                 :            :     else {
        2924                 :          4 :         Py_DECREF(result);
        2925                 :            :     }
        2926                 :          4 :     Py_DECREF(threading);
        2927                 :            : }
        2928                 :            :
        2929                 :            : #define NEXITFUNCS 32
        2930                 :          0 : int Py_AtExit(void (*func)(void))
        2931                 :            : {
        2932         [ #  # ]:          0 :     if (_PyRuntime.nexitfuncs >= NEXITFUNCS)
        2933                 :          0 :         return -1;
        2934                 :          0 :     _PyRuntime.exitfuncs[_PyRuntime.nexitfuncs++] = func;
        2935                 :          0 :     return 0;
        2936                 :            : }
        2937                 :            :
        2938                 :            : static void
        2939                 :         25 : call_ll_exitfuncs(_PyRuntimeState *runtime)
        2940                 :            : {
        2941         [ -  + ]:         25 :     while (runtime->nexitfuncs > 0) {
        2942                 :            :         /* pop last function from the list */
        2943                 :          0 :         runtime->nexitfuncs--;
        2944                 :          0 :         void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs];
        2945                 :          0 :         runtime->exitfuncs[runtime->nexitfuncs] = NULL;
        2946                 :            :
        2947                 :          0 :         exitfunc();
        2948                 :            :     }
        2949                 :            :
        2950                 :         25 :     fflush(stdout);
        2951                 :         25 :     fflush(stderr);
        2952                 :         25 : }
        2953                 :            :
        2954                 :            : void _Py_NO_RETURN
        2955                 :          0 : Py_Exit(int sts)
        2956                 :            : {
        2957         [ #  # ]:          0 :     if (Py_FinalizeEx() < 0) {
        2958                 :          0 :         sts = 120;
        2959                 :            :     }
        2960                 :            :
        2961                 :          0 :     exit(sts);
        2962                 :            : }
        2963                 :            :
        2964                 :            :
        2965                 :            : /*
        2966                 :            :  * The file descriptor fd is considered ``interactive'' if either
        2967                 :            :  *   a) isatty(fd) is TRUE, or
        2968                 :            :  *   b) the -i flag was given, and the filename associated with
        2969                 :            :  *      the descriptor is NULL or "<stdin>" or "???".
        2970                 :            :  */
        2971                 :            : int
        2972                 :          0 : Py_FdIsInteractive(FILE *fp, const char *filename)
        2973                 :            : {
        2974         [ #  # ]:          0 :     if (isatty(fileno(fp))) {
        2975                 :          0 :         return 1;
        2976                 :            :     }
        2977         [ #  # ]:          0 :     if (!_Py_GetConfig()->interactive) {
        2978                 :          0 :         return 0;
        2979                 :            :     }
        2980                 :            :     return ((filename == NULL)
        2981         [ #  # ]:          0 :             || (strcmp(filename, "<stdin>") == 0)
        2982   [ #  #  #  # ]:          0 :             || (strcmp(filename, "???") == 0));
        2983                 :            : }
        2984                 :            :
        2985                 :            :
        2986                 :            : int
        2987                 :         22 : _Py_FdIsInteractive(FILE *fp, PyObject *filename)
        2988                 :            : {
        2989         [ -  + ]:         22 :     if (isatty(fileno(fp))) {
        2990                 :          0 :         return 1;
        2991                 :            :     }
        2992         [ +  - ]:         22 :     if (!_Py_GetConfig()->interactive) {
        2993                 :         22 :         return 0;
        2994                 :            :     }
        2995                 :            :     return ((filename == NULL)
        2996         [ #  # ]:          0 :             || (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0)
        2997   [ #  #  #  # ]:          0 :             || (PyUnicode_CompareWithASCIIString(filename, "???") == 0));
        2998                 :            : }
        2999                 :            :
        3000                 :            :
        3001                 :            : /* Wrappers around sigaction() or signal(). */
        3002                 :            :
        3003                 :            : PyOS_sighandler_t
        3004                 :        320 : PyOS_getsig(int sig)
        3005                 :            : {
        3006                 :            : #ifdef HAVE_SIGACTION
        3007                 :            :     struct sigaction context;
        3008         [ +  + ]:        320 :     if (sigaction(sig, NULL, &context) == -1)
        3009                 :         10 :         return SIG_ERR;
        3010                 :        310 :     return context.sa_handler;
        3011                 :            : #else
        3012                 :            :     PyOS_sighandler_t handler;
        3013                 :            : /* Special signal handling for the secure CRT in Visual Studio 2005 */
        3014                 :            : #if defined(_MSC_VER) && _MSC_VER >= 1400
        3015                 :            :     switch (sig) {
        3016                 :            :     /* Only these signals are valid */
        3017                 :            :     case SIGINT:
        3018                 :            :     case SIGILL:
        3019                 :            :     case SIGFPE:
        3020                 :            :     case SIGSEGV:
        3021                 :            :     case SIGTERM:
        3022                 :            :     case SIGBREAK:
        3023                 :            :     case SIGABRT:
        3024                 :            :         break;
        3025                 :            :     /* Don't call signal() with other values or it will assert */
        3026                 :            :     default:
        3027                 :            :         return SIG_ERR;
        3028                 :            :     }
        3029                 :            : #endif /* _MSC_VER && _MSC_VER >= 1400 */
        3030                 :            :     handler = signal(sig, SIG_IGN);
        3031                 :            :     if (handler != SIG_ERR)
        3032                 :            :         signal(sig, handler);
        3033                 :            :     return handler;
        3034                 :            : #endif
        3035                 :            : }
        3036                 :            :
        3037                 :            : /*
        3038                 :            :  * All of the code in this function must only use async-signal-safe functions,
        3039                 :            :  * listed at `man 7 signal` or
        3040                 :            :  * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
        3041                 :            :  */
        3042                 :            : PyOS_sighandler_t
        3043                 :         17 : PyOS_setsig(int sig, PyOS_sighandler_t handler)
        3044                 :            : {
        3045                 :            : #ifdef HAVE_SIGACTION
        3046                 :            :     /* Some code in Modules/signalmodule.c depends on sigaction() being
        3047                 :            :      * used here if HAVE_SIGACTION is defined.  Fix that if this code
        3048                 :            :      * changes to invalidate that assumption.
        3049                 :            :      */
        3050                 :            :     struct sigaction context, ocontext;
        3051                 :         17 :     context.sa_handler = handler;
        3052                 :         17 :     sigemptyset(&context.sa_mask);
        3053                 :            :     /* Using SA_ONSTACK is friendlier to other C/C++/Golang-VM code that
        3054                 :            :      * extension module or embedding code may use where tiny thread stacks
        3055                 :            :      * are used.  https://bugs.python.org/issue43390 */
        3056                 :         17 :     context.sa_flags = SA_ONSTACK;
        3057         [ -  + ]:         17 :     if (sigaction(sig, &context, &ocontext) == -1)
        3058                 :          0 :         return SIG_ERR;
        3059                 :         17 :     return ocontext.sa_handler;
        3060                 :            : #else
        3061                 :            :     PyOS_sighandler_t oldhandler;
        3062                 :            :     oldhandler = signal(sig, handler);
        3063                 :            : #ifdef HAVE_SIGINTERRUPT
        3064                 :            :     siginterrupt(sig, 1);
        3065                 :            : #endif
        3066                 :            :     return oldhandler;
        3067                 :            : #endif
        3068                 :            : }
        3069                 :            :
        3070                 :            : #ifdef __cplusplus
        3071                 :            : }
        3072                 :            : #endif

Generated by: LCOV version 1.14