From 1c7ade5284e8c7e245b50b51918fa30e9a877b99 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 18 Jan 2012 16:13:31 +0100 Subject: [PATCH 1/2] Fix leaking a RuntimeError objects when creating sub-interpreters --- Objects/exceptions.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 0106ba3df52..fc41853d265 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2093,27 +2093,29 @@ _PyExc_Init(void) preallocate_memerrors(); - PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); - if (!PyExc_RecursionErrorInst) - Py_FatalError("Cannot pre-allocate RuntimeError instance for " - "recursion errors"); - else { - PyBaseExceptionObject *err_inst = - (PyBaseExceptionObject *)PyExc_RecursionErrorInst; - PyObject *args_tuple; - PyObject *exc_message; - exc_message = PyUnicode_FromString("maximum recursion depth exceeded"); - if (!exc_message) - Py_FatalError("cannot allocate argument for RuntimeError " - "pre-allocation"); - args_tuple = PyTuple_Pack(1, exc_message); - if (!args_tuple) - Py_FatalError("cannot allocate tuple for RuntimeError " - "pre-allocation"); - Py_DECREF(exc_message); - if (BaseException_init(err_inst, args_tuple, NULL)) - Py_FatalError("init of pre-allocated RuntimeError failed"); - Py_DECREF(args_tuple); + if (!PyExc_RecursionErrorInst) { + PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); + if (!PyExc_RecursionErrorInst) + Py_FatalError("Cannot pre-allocate RuntimeError instance for " + "recursion errors"); + else { + PyBaseExceptionObject *err_inst = + (PyBaseExceptionObject *)PyExc_RecursionErrorInst; + PyObject *args_tuple; + PyObject *exc_message; + exc_message = PyUnicode_FromString("maximum recursion depth exceeded"); + if (!exc_message) + Py_FatalError("cannot allocate argument for RuntimeError " + "pre-allocation"); + args_tuple = PyTuple_Pack(1, exc_message); + if (!args_tuple) + Py_FatalError("cannot allocate tuple for RuntimeError " + "pre-allocation"); + Py_DECREF(exc_message); + if (BaseException_init(err_inst, args_tuple, NULL)) + Py_FatalError("init of pre-allocated RuntimeError failed"); + Py_DECREF(args_tuple); + } } Py_DECREF(bltinmod); From fc1b6f0078a6bda75b571ee7877328c8ca82877d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 18 Jan 2012 16:13:56 +0100 Subject: [PATCH 2/2] Fix the _io module leaking references when a sub-interpreter is created. --- Modules/_io/_iomodule.c | 84 ++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 44bdac6b5cf..61362c73b2a 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -741,58 +741,46 @@ PyInit__io(void) ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); /* Interned strings */ - if (!(_PyIO_str_close = PyUnicode_InternFromString("close"))) +#define ADD_INTERNED(name) \ + if (!_PyIO_str_ ## name && \ + !(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \ goto fail; - if (!(_PyIO_str_closed = PyUnicode_InternFromString("closed"))) + + ADD_INTERNED(close) + ADD_INTERNED(closed) + ADD_INTERNED(decode) + ADD_INTERNED(encode) + ADD_INTERNED(fileno) + ADD_INTERNED(flush) + ADD_INTERNED(getstate) + ADD_INTERNED(isatty) + ADD_INTERNED(newlines) + ADD_INTERNED(read) + ADD_INTERNED(read1) + ADD_INTERNED(readable) + ADD_INTERNED(readinto) + ADD_INTERNED(readline) + ADD_INTERNED(reset) + ADD_INTERNED(seek) + ADD_INTERNED(seekable) + ADD_INTERNED(setstate) + ADD_INTERNED(tell) + ADD_INTERNED(truncate) + ADD_INTERNED(write) + ADD_INTERNED(writable) + + if (!_PyIO_str_nl && + !(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) goto fail; - if (!(_PyIO_str_decode = PyUnicode_InternFromString("decode"))) + + if (!_PyIO_empty_str && + !(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) goto fail; - if (!(_PyIO_str_encode = PyUnicode_InternFromString("encode"))) + if (!_PyIO_empty_bytes && + !(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) goto fail; - if (!(_PyIO_str_fileno = PyUnicode_InternFromString("fileno"))) - goto fail; - if (!(_PyIO_str_flush = PyUnicode_InternFromString("flush"))) - goto fail; - if (!(_PyIO_str_getstate = PyUnicode_InternFromString("getstate"))) - goto fail; - if (!(_PyIO_str_isatty = PyUnicode_InternFromString("isatty"))) - goto fail; - if (!(_PyIO_str_newlines = PyUnicode_InternFromString("newlines"))) - goto fail; - if (!(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) - goto fail; - if (!(_PyIO_str_read = PyUnicode_InternFromString("read"))) - goto fail; - if (!(_PyIO_str_read1 = PyUnicode_InternFromString("read1"))) - goto fail; - if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable"))) - goto fail; - if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto"))) - goto fail; - if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline"))) - goto fail; - if (!(_PyIO_str_reset = PyUnicode_InternFromString("reset"))) - goto fail; - if (!(_PyIO_str_seek = PyUnicode_InternFromString("seek"))) - goto fail; - if (!(_PyIO_str_seekable = PyUnicode_InternFromString("seekable"))) - goto fail; - if (!(_PyIO_str_setstate = PyUnicode_InternFromString("setstate"))) - goto fail; - if (!(_PyIO_str_tell = PyUnicode_InternFromString("tell"))) - goto fail; - if (!(_PyIO_str_truncate = PyUnicode_InternFromString("truncate"))) - goto fail; - if (!(_PyIO_str_write = PyUnicode_InternFromString("write"))) - goto fail; - if (!(_PyIO_str_writable = PyUnicode_InternFromString("writable"))) - goto fail; - - if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) - goto fail; - if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) - goto fail; - if (!(_PyIO_zero = PyLong_FromLong(0L))) + if (!_PyIO_zero && + !(_PyIO_zero = PyLong_FromLong(0L))) goto fail; state->initialized = 1;