diff options
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 101 | 
1 files changed, 69 insertions, 32 deletions
| diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 9ef653b57a..37dc3b8dc8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -35,12 +35,30 @@  #define PATH_MAX MAXPATHLEN  #endif +#ifdef Py_REF_DEBUG +static +void _print_total_refs(void) { +    PyObject *xoptions, *key, *value; +    xoptions = PySys_GetXOptions(); +    if (xoptions == NULL) +        return; +    key = PyUnicode_FromString("showrefcount"); +    if (key == NULL) +        return; +    value = PyDict_GetItem(xoptions, key); +    Py_DECREF(key); +    if (value == Py_True) +        fprintf(stderr, +                "[%" PY_FORMAT_SIZE_T "d refs, " +                "%" PY_FORMAT_SIZE_T "d blocks]\n", +                _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); +} +#endif +  #ifndef Py_REF_DEBUG  #define PRINT_TOTAL_REFS()  #else /* Py_REF_DEBUG */ -#define PRINT_TOTAL_REFS() fprintf(stderr,                              \ -                   "[%" PY_FORMAT_SIZE_T "d refs]\n",                   \ -                   _Py_GetRefTotal()) +#define PRINT_TOTAL_REFS() _print_total_refs()  #endif  #ifdef __cplusplus @@ -68,6 +86,7 @@ static void call_py_exitfuncs(void);  static void wait_for_thread_shutdown(void);  static void call_ll_exitfuncs(void);  extern int _PyUnicode_Init(void); +extern int _PyStructSequence_Init(void);  extern void _PyUnicode_Fini(void);  extern int _PyLong_Init(void);  extern void PyLong_Fini(void); @@ -93,6 +112,7 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */  int Py_NoUserSiteDirectory = 0; /* for -s and site.py */  int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */  int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ +int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */  PyThreadState *_Py_Finalizing = NULL; @@ -156,7 +176,7 @@ get_codec_name(const char *encoding)      name_utf8 = _PyUnicode_AsString(name);      if (name_utf8 == NULL)          goto error; -    name_str = strdup(name_utf8); +    name_str = _PyMem_RawStrdup(name_utf8);      Py_DECREF(name);      if (name_str == NULL) {          PyErr_NoMemory(); @@ -309,7 +329,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)      if (!PyByteArray_Init())          Py_FatalError("Py_Initialize: can't init bytearray"); -    _PyFloat_Init(); +    if (!_PyFloat_Init()) +        Py_FatalError("Py_Initialize: can't init float");      interp->modules = PyDict_New();      if (interp->modules == NULL) @@ -318,6 +339,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)      /* Init Unicode implementation; relies on the codec registry */      if (_PyUnicode_Init() < 0)          Py_FatalError("Py_Initialize: can't initialize unicode"); +    if (_PyStructSequence_Init() < 0) +        Py_FatalError("Py_Initialize: can't initialize structseq");      bimod = _PyBuiltin_Init();      if (bimod == NULL) @@ -526,10 +549,6 @@ Py_Finalize(void)      while (PyGC_Collect() > 0)          /* nothing */;  #endif -    /* We run this while most interpreter state is still alive, so that -       debug information can be printed out */ -    _PyGC_Fini(); -      /* Destroy all modules */      PyImport_Cleanup(); @@ -592,11 +611,6 @@ Py_Finalize(void)      _PyExc_Fini(); -    /* Cleanup auto-thread-state */ -#ifdef WITH_THREAD -    _PyGILState_Fini(); -#endif /* WITH_THREAD */ -      /* Sundry finalizers */      PyMethod_Fini();      PyFrame_Fini(); @@ -610,17 +624,14 @@ Py_Finalize(void)      PyFloat_Fini();      PyDict_Fini();      PySlice_Fini(); +    _PyGC_Fini();      /* Cleanup Unicode implementation */      _PyUnicode_Fini(); -    /* Delete current thread. After this, many C API calls become crashy. */ -    PyThreadState_Swap(NULL); -    PyInterpreterState_Delete(interp); -      /* reset file system default encoding */      if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { -        free((char*)Py_FileSystemDefaultEncoding); +        PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);          Py_FileSystemDefaultEncoding = NULL;      } @@ -632,6 +643,15 @@ Py_Finalize(void)      PyGrammar_RemoveAccelerators(&_PyParser_Grammar); +    /* Cleanup auto-thread-state */ +#ifdef WITH_THREAD +    _PyGILState_Fini(); +#endif /* WITH_THREAD */ + +    /* Delete current thread. After this, many C API calls become crashy. */ +    PyThreadState_Swap(NULL); +    PyInterpreterState_Delete(interp); +  #ifdef Py_TRACE_REFS      /* Display addresses (& refcnts) of all objects still alive.       * An address can be used to find the repr of the object, printed @@ -769,6 +789,9 @@ Py_EndInterpreter(PyThreadState *tstate)          Py_FatalError("Py_EndInterpreter: thread is not current");      if (tstate->frame != NULL)          Py_FatalError("Py_EndInterpreter: thread still has a frame"); + +    wait_for_thread_shutdown(); +      if (tstate != interp->tstate_head || tstate->next != NULL)          Py_FatalError("Py_EndInterpreter: not the last thread"); @@ -827,7 +850,7 @@ Py_GetPythonHome(void)  static void  initmain(PyInterpreterState *interp)  { -    PyObject *m, *d; +    PyObject *m, *d, *loader;      m = PyImport_AddModule("__main__");      if (m == NULL)          Py_FatalError("can't create __main__ module"); @@ -848,7 +871,8 @@ initmain(PyInterpreterState *interp)       * be set if __main__ gets further initialized later in the startup       * process.       */ -    if (PyDict_GetItemString(d, "__loader__") == NULL) { +    loader = PyDict_GetItemString(d, "__loader__"); +    if (loader == NULL || loader == Py_None) {          PyObject *loader = PyObject_GetAttrString(interp->importlib,                                                    "BuiltinImporter");          if (loader == NULL) { @@ -898,6 +922,7 @@ initsite(void)      PyObject *m;      m = PyImport_ImportModule("site");      if (m == NULL) { +        fprintf(stderr, "Failed to import the site module\n");          PyErr_Print();          Py_Finalize();          exit(1); @@ -1065,7 +1090,11 @@ initstdio(void)      encoding = Py_GETENV("PYTHONIOENCODING");      errors = NULL;      if (encoding) { -        encoding = strdup(encoding); +        encoding = _PyMem_Strdup(encoding); +        if (encoding == NULL) { +            PyErr_NoMemory(); +            goto error; +        }          errors = strchr(encoding, ':');          if (errors) {              *errors = '\0'; @@ -1124,18 +1153,24 @@ initstdio(void)         when import.c tries to write to stderr in verbose mode. */      encoding_attr = PyObject_GetAttrString(std, "encoding");      if (encoding_attr != NULL) { -        const char * encoding; -        encoding = _PyUnicode_AsString(encoding_attr); -        if (encoding != NULL) { -            PyObject *codec_info = _PyCodec_Lookup(encoding); +        const char * std_encoding; +        std_encoding = _PyUnicode_AsString(encoding_attr); +        if (std_encoding != NULL) { +            PyObject *codec_info = _PyCodec_Lookup(std_encoding);              Py_XDECREF(codec_info);          }          Py_DECREF(encoding_attr);      }      PyErr_Clear();  /* Not a fatal error if codec isn't available */ -    PySys_SetObject("__stderr__", std); -    PySys_SetObject("stderr", std); +    if (PySys_SetObject("__stderr__", std) < 0) { +        Py_DECREF(std); +        goto error; +    } +    if (PySys_SetObject("stderr", std) < 0) { +        Py_DECREF(std); +        goto error; +    }      Py_DECREF(std);  #endif @@ -1144,8 +1179,7 @@ initstdio(void)          status = -1;      } -    if (encoding) -        free(encoding); +    PyMem_Free(encoding);      Py_XDECREF(bimod);      Py_XDECREF(iomod);      return status; @@ -1352,8 +1386,8 @@ maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)      return 0;  } -int -static set_main_loader(PyObject *d, const char *filename, const char *loader_name) +static int +set_main_loader(PyObject *d, const char *filename, const char *loader_name)  {      PyInterpreterState *interp;      PyThreadState *tstate; @@ -2459,6 +2493,9 @@ initsigs(void)      PyOS_setsig(SIGXFSZ, SIG_IGN);  #endif      PyOS_InitInterrupts(); /* May imply initsignal() */ +    if (PyErr_Occurred()) { +        Py_FatalError("Py_Initialize: can't import signal"); +    }  } | 
