From 350e0ff264038e3790d0182134de7959965dea7d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 9 Dec 2012 14:28:26 +0100 Subject: Issue #13390: New function :func:`sys.getallocatedblocks()` returns the number of memory blocks currently allocated. Also, the ``-R`` option to regrtest uses this function to guard against memory allocation leaks. --- Python/pythonrun.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index dd32017574..f0d8550773 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -38,9 +38,10 @@ #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() fprintf(stderr, \ + "[%" PY_FORMAT_SIZE_T "d refs, " \ + "%" PY_FORMAT_SIZE_T "d blocks]\n", \ + _Py_GetRefTotal(), _Py_GetAllocatedBlocks()) #endif #ifdef __cplusplus -- cgit v1.2.1 From b66f6b5c73f6eda0d24bea66059da1fa7f651aa4 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Tue, 26 Mar 2013 01:59:56 +0200 Subject: #17323: The "[X refs, Y blocks]" printed by debug builds has been disabled by default. It can be re-enabled with the `-X showrefcount` option. --- Python/pythonrun.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f0d8550773..751008ac30 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -35,13 +35,29 @@ #define PATH_MAX MAXPATHLEN #endif +#ifdef Py_REF_DEBUG +void _print_total_refs() { + 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, " \ - "%" PY_FORMAT_SIZE_T "d blocks]\n", \ - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()) +#define PRINT_TOTAL_REFS() _print_total_refs() #endif #ifdef __cplusplus -- cgit v1.2.1 From 77fee69c3d917426c31557ec45eec4f72a51877f Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 24 Apr 2013 20:17:53 +0200 Subject: Issue #17832: fix a compilation warning about a function prototype. Also, make the private function static. --- Python/pythonrun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 751008ac30..0cd695f36e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -36,7 +36,8 @@ #endif #ifdef Py_REF_DEBUG -void _print_total_refs() { +static +void _print_total_refs(void) { PyObject *xoptions, *key, *value; xoptions = PySys_GetXOptions(); if (xoptions == NULL) -- cgit v1.2.1 From 0010471202cc1a3eff955f556a247c78e7e2c34b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 4 May 2013 13:56:58 -0400 Subject: #17115,17116: Have modules initialize the __package__ and __loader__ attributes to None. The long-term goal is for people to be able to rely on these attributes existing and checking for None to see if they have been set. Since import itself sets these attributes when a loader does not the only instances when the attributes are None are from someone overloading __import__() and not using a loader or someone creating a module from scratch. This patch also unifies module initialization. Before you could have different attributes with default values depending on how the module object was created. Now the only way to not get the same default set of attributes is to circumvent initialization by calling ModuleType.__new__() directly. --- Python/pythonrun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index b92a8bd9b4..40f6ab4cee 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -866,7 +866,8 @@ initmain(PyInterpreterState *interp) * be set if __main__ gets further initialized later in the startup * process. */ - if (PyDict_GetItemString(d, "__loader__") == NULL) { + PyObject *loader = PyDict_GetItemString(d, "__loader__"); + if (loader == NULL || loader == Py_None) { PyObject *loader = PyObject_GetAttrString(interp->importlib, "BuiltinImporter"); if (loader == NULL) { -- cgit v1.2.1 From 39da2cb53bcacdaeb61d98d5511dbd44b423f080 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 4 May 2013 17:37:09 -0400 Subject: #17115: I hate you MS for not supporting C99. --- Python/pythonrun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 75f1ef6a26..cf2ecf1cb1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -843,7 +843,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"); @@ -864,7 +864,7 @@ initmain(PyInterpreterState *interp) * be set if __main__ gets further initialized later in the startup * process. */ - PyObject *loader = PyDict_GetItemString(d, "__loader__"); + loader = PyDict_GetItemString(d, "__loader__"); if (loader == NULL || loader == Py_None) { PyObject *loader = PyObject_GetAttrString(interp->importlib, "BuiltinImporter"); -- cgit v1.2.1 From 5756d7dace379752116766907b63ac77ffc4bc98 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 6 May 2013 21:15:57 +0200 Subject: Issue #1545463: Global variables caught in reference cycles are now garbage-collected at shutdown. --- Python/pythonrun.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 96b0988ec7..02a4329950 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -544,10 +544,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(); @@ -628,6 +624,7 @@ Py_Finalize(void) PyFloat_Fini(); PyDict_Fini(); PySlice_Fini(); + _PyGC_Fini(); /* Cleanup Unicode implementation */ _PyUnicode_Fini(); -- cgit v1.2.1 From 37c223a89b1cd652ae397b07915c2dad168d3a0a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 7 Jul 2013 15:50:49 +0200 Subject: Issue #18203: Fix Py_Finalize(): destroy the GIL after the last call to PyMem_Malloc() or PyObject_Malloc(). For example, PyCFunction_Fini() calls PyObject_GC_Del() which calls PyObject_FREE(). --- Python/pythonrun.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 02a4329950..94175be87e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -606,11 +606,6 @@ Py_Finalize(void) _PyExc_Fini(); - /* Cleanup auto-thread-state */ -#ifdef WITH_THREAD - _PyGILState_Fini(); -#endif /* WITH_THREAD */ - /* Sundry finalizers */ PyMethod_Fini(); PyFrame_Fini(); @@ -629,10 +624,6 @@ Py_Finalize(void) /* 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); @@ -647,6 +638,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 -- cgit v1.2.1 From 28ee3a69061fefad791404c84825222db9c7d0f2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 7 Jul 2013 23:30:24 +0200 Subject: Issue #18203: Add _PyMem_RawStrdup() and _PyMem_Strdup() Replace strdup() with _PyMem_RawStrdup() or _PyMem_Strdup(), depending if the GIL is held or not. --- Python/pythonrun.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 94175be87e..d95a09d4a7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -174,7 +174,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(); @@ -626,7 +626,7 @@ Py_Finalize(void) /* reset file system default encoding */ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { - free((char*)Py_FileSystemDefaultEncoding); + PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; } @@ -1081,7 +1081,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'; @@ -1140,10 +1144,10 @@ 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); @@ -1160,8 +1164,7 @@ initstdio(void) status = -1; } - if (encoding) - free(encoding); + PyMem_Free(encoding); Py_XDECREF(bimod); Py_XDECREF(iomod); return status; -- cgit v1.2.1 From 485316200dd2089a50ed5b41f2041bd1a8603622 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 17 Jul 2013 01:22:45 +0200 Subject: Close #18469: Replace PyDict_GetItemString() with _PyDict_GetItemId() in structseq.c _PyDict_GetItemId() is more efficient: it only builds the Unicode string once. Identifiers (dictionary keys) are now created at Python initialization, and if the creation failed, Python does exit with a fatal error. Before, PyDict_GetItemString() failure was not handled: structseq_new() could call PyObject_GC_NewVar() with a negative size, and structseq_dealloc() could also crash. --- Python/pythonrun.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index d95a09d4a7..814220b40e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -86,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); @@ -336,6 +337,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) -- cgit v1.2.1 From 7b7c6fa589acf72320bf1e20d7928e0b3934bd38 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 21 Jul 2013 13:25:51 +0200 Subject: Issue #18520: Fix initsigs(), handle PyOS_InitInterrupts() error PyOS_InitInterrupts() can raise error when importing the signal module --- Python/pythonrun.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 814220b40e..040172bb3d 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2481,6 +2481,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"); + } } -- cgit v1.2.1 From 92d3e3cf6bfe7320aea27780a6525e6075624935 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Jul 2013 22:24:54 +0200 Subject: Issue #18520: Add a new PyStructSequence_InitType2() function, same than PyStructSequence_InitType() except that it has a return value (0 on success, -1 on error). * PyStructSequence_InitType2() now raises MemoryError on memory allocation failure * Fix also some calls to PyDict_SetItemString(): handle error --- Python/pythonrun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 040172bb3d..edf9b6b542 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -328,7 +328,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) -- cgit v1.2.1 From ba92a0f1543b48abeccafc1ecf5d1246bd6bf27d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Jul 2013 22:53:28 +0200 Subject: Issue #18520: initsite() is a little bit more verbose when import site fails --- Python/pythonrun.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index edf9b6b542..30e5e6f0c3 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -918,6 +918,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); -- cgit v1.2.1 From 7196af1e77661d5981f36256a627831392e8c220 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Jul 2013 23:55:19 +0200 Subject: Issue #18520: Fix initstdio(), handle PySys_SetObject() failure --- Python/pythonrun.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 30e5e6f0c3..18c2baa656 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1159,8 +1159,14 @@ initstdio(void) } 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 -- cgit v1.2.1