summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-12-06 17:12:59 (GMT)
committerGitHub <noreply@github.com>2017-12-06 17:12:59 (GMT)
commit92a3c6f493ad411e4cf0acdf305ef4876aa90669 (patch)
tree67cae429f766b6f99a69a303cf3960dd7893859f /Python
parent1b4587a2462fc05a14be87123083322103a1f55b (diff)
downloadcpython-92a3c6f493ad411e4cf0acdf305ef4876aa90669.zip
cpython-92a3c6f493ad411e4cf0acdf305ef4876aa90669.tar.gz
cpython-92a3c6f493ad411e4cf0acdf305ef4876aa90669.tar.bz2
bpo-32030: Add _PyImport_Fini2() (#4737)
PyImport_ExtendInittab() now uses PyMem_RawRealloc() rather than PyMem_Realloc(). PyImport_ExtendInittab() can be called before Py_Initialize() whereas only the PyMem_Raw allocator is supposed to be used before Py_Initialize(). Add _PyImport_Fini2() to release the memory allocated by PyImport_ExtendInittab() at exit. PyImport_ExtendInittab() now forces the usage of the default raw allocator, to be able to release memory in _PyImport_Fini2(). Don't export these functions anymore to be C API, only to Py_BUILD_CORE: * _PyExc_Fini() * _PyImport_Fini() * _PyGC_DumpShutdownStats() * _PyGC_Fini() * _PyType_Fini() * _Py_HashRandomization_Fini()
Diffstat (limited to 'Python')
-rw-r--r--Python/import.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/Python/import.c b/Python/import.c
index 9a98573..cc7417b 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -30,6 +30,7 @@ static PyObject *extensions = NULL;
extern struct _inittab _PyImport_Inittab[];
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
+static struct _inittab *inittab_copy = NULL;
/*[clinic input]
module _imp
@@ -285,6 +286,19 @@ _PyImport_Fini(void)
}
}
+void
+_PyImport_Fini2(void)
+{
+ /* Use the same memory allocator than PyImport_ExtendInittab(). */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ /* Free memory allocated by PyImport_ExtendInittab() */
+ PyMem_RawFree(inittab_copy);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
/* Helper for sys */
PyObject *
@@ -2233,9 +2247,9 @@ PyInit_imp(void)
int
PyImport_ExtendInittab(struct _inittab *newtab)
{
- static struct _inittab *our_copy = NULL;
struct _inittab *p;
- int i, n;
+ Py_ssize_t i, n;
+ int res = 0;
/* Count the number of entries in both tables */
for (n = 0; newtab[n].name != NULL; n++)
@@ -2245,19 +2259,35 @@ PyImport_ExtendInittab(struct _inittab *newtab)
for (i = 0; PyImport_Inittab[i].name != NULL; i++)
;
+ /* Force default raw memory allocator to get a known allocator to be able
+ to release the memory in _PyImport_Fini2() */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
/* Allocate new memory for the combined table */
- p = our_copy;
- PyMem_RESIZE(p, struct _inittab, i+n+1);
- if (p == NULL)
- return -1;
+ if ((i + n + 1) <= PY_SSIZE_T_MAX / sizeof(struct _inittab)) {
+ size_t size = sizeof(struct _inittab) * (i + n + 1);
+ p = PyMem_RawRealloc(inittab_copy, size);
+ }
+ else {
+ p = NULL;
+ }
+ if (p == NULL) {
+ res = -1;
+ goto done;
+ }
- /* Copy the tables into the new memory */
- if (our_copy != PyImport_Inittab)
+ /* Copy the tables into the new memory at the first call
+ to PyImport_ExtendInittab(). */
+ if (inittab_copy != PyImport_Inittab) {
memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
- PyImport_Inittab = our_copy = p;
- memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab));
+ }
+ memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab));
+ PyImport_Inittab = inittab_copy = p;
- return 0;
+done:
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return res;
}
/* Shorthand to add a single entry given a name and a function */