mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Fix:
* crashes on memory allocation failure found with failmalloc
 * memory leaks found with valgrind
 * compiler warnings in opt mode which would lead to invalid memory reads
 * problem using wrong name in decimal module reported by pychecker
Update the valgrind suppressions file with new leaks that are small/one-time
leaks we don't care about (ie, they are too hard to fix).
TBR=barry
TESTED=./python -E -tt ./Lib/test/regrtest.py -uall (both debug and opt modes)
  in opt mode:
  valgrind -q --leak-check=yes --suppressions=Misc/valgrind-python.supp \
    ./python -E -tt ./Lib/test/regrtest.py -uall,-bsddb,-compiler \
                        -x test_logging test_ssl test_multiprocessing
  valgrind -q --leak-check=yes --suppressions=Misc/valgrind-python.supp \
    ./python -E -tt ./Lib/test/regrtest.py test_multiprocessing
  for i in `seq 1 4000` ; do
    LD_PRELOAD=~/local/lib/libfailmalloc.so FAILMALLOC_INTERVAL=$i \
        ./python -c pass
  done
At least some of these fixes should probably be backported to 2.5.
			
			
This commit is contained in:
		
							parent
							
								
									21d2ab7fe8
								
							
						
					
					
						commit
						18aa388ca0
					
				
					 10 changed files with 75 additions and 14 deletions
				
			
		|  | @ -5061,7 +5061,7 @@ def _dlog10(c, e, p): | ||||||
|         log_tenpower = f*M # exact |         log_tenpower = f*M # exact | ||||||
|     else: |     else: | ||||||
|         log_d = 0  # error < 2.31 |         log_d = 0  # error < 2.31 | ||||||
|         log_tenpower = div_nearest(f, 10**-p) # error < 0.5 |         log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 | ||||||
| 
 | 
 | ||||||
|     return _div_nearest(log_tenpower+log_d, 100) |     return _div_nearest(log_tenpower+log_d, 100) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,14 @@ What's New in Python 2.6 release candidate 1? | ||||||
| Core and Builtins | Core and Builtins | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
|  | - Fix crashes on memory allocation failure found with failmalloc. | ||||||
|  | 
 | ||||||
|  | - Fix memory leaks found with valgrind and update suppressions file. | ||||||
|  | 
 | ||||||
|  | - Fix compiler warnings in opt mode which would lead to invalid memory reads. | ||||||
|  | 
 | ||||||
|  | - Fix problem using wrong name in decimal module reported by pychecker. | ||||||
|  | 
 | ||||||
| - Issue #3642: Changed type of numarenas from uint to size_t | - Issue #3642: Changed type of numarenas from uint to size_t | ||||||
|   in order to silence a compilier warning on 64bit OSes. |   in order to silence a compilier warning on 64bit OSes. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -46,6 +46,39 @@ | ||||||
| #    Will need to fix that. | #    Will need to fix that. | ||||||
| # | # | ||||||
| 
 | 
 | ||||||
|  | { | ||||||
|  |    Suppress leaking the GIL.  Happens once per process, see comment in ceval.c. | ||||||
|  |    Memcheck:Leak | ||||||
|  |    fun:malloc | ||||||
|  |    fun:PyThread_allocate_lock | ||||||
|  |    fun:PyEval_InitThreads | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | { | ||||||
|  |    Suppress leaking the GIL after a fork. | ||||||
|  |    Memcheck:Leak | ||||||
|  |    fun:malloc | ||||||
|  |    fun:PyThread_allocate_lock | ||||||
|  |    fun:PyEval_ReInitThreads | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | { | ||||||
|  |    Suppress leaking the autoTLSkey.  This looks like it shouldn't leak though. | ||||||
|  |    Memcheck:Leak | ||||||
|  |    fun:malloc | ||||||
|  |    fun:PyThread_create_key | ||||||
|  |    fun:_PyGILState_Init | ||||||
|  |    fun:Py_InitializeEx | ||||||
|  |    fun:Py_Main | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | { | ||||||
|  |    Hmmm, is this a real leak or like the GIL? | ||||||
|  |    Memcheck:Leak | ||||||
|  |    fun:malloc | ||||||
|  |    fun:PyThread_ReInitTLS | ||||||
|  | } | ||||||
|  | 
 | ||||||
| { | { | ||||||
|    Handle PyMalloc confusing valgrind (possibly leaked) |    Handle PyMalloc confusing valgrind (possibly leaked) | ||||||
|    Memcheck:Leak |    Memcheck:Leak | ||||||
|  |  | ||||||
|  | @ -416,6 +416,7 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) | ||||||
| 		ffi_ofs = 0; | 		ffi_ofs = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	assert(stgdict->format == NULL); | ||||||
| 	if (isStruct && !isPacked) { | 	if (isStruct && !isPacked) { | ||||||
| 		stgdict->format = alloc_format_string(NULL, "T{"); | 		stgdict->format = alloc_format_string(NULL, "T{"); | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -539,7 +540,9 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) | ||||||
| #undef realdict | #undef realdict | ||||||
| 
 | 
 | ||||||
| 	if (isStruct && !isPacked) { | 	if (isStruct && !isPacked) { | ||||||
|  | 		char *ptr = stgdict->format; | ||||||
| 		stgdict->format = alloc_format_string(stgdict->format, "}"); | 		stgdict->format = alloc_format_string(stgdict->format, "}"); | ||||||
|  | 		PyMem_Free(ptr); | ||||||
| 		if (stgdict->format == NULL) | 		if (stgdict->format == NULL) | ||||||
| 			return -1; | 			return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -278,6 +278,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) | ||||||
| 	ret = -1; | 	ret = -1; | ||||||
| 
 | 
 | ||||||
|  done: |  done: | ||||||
|  | 	PyMem_Free(name); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -784,7 +784,8 @@ initsignal(void) | ||||||
| #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) | #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) | ||||||
|     ItimerError = PyErr_NewException("signal.ItimerError",  |     ItimerError = PyErr_NewException("signal.ItimerError",  | ||||||
|          PyExc_IOError, NULL); |          PyExc_IOError, NULL); | ||||||
|     PyDict_SetItemString(d, "ItimerError", ItimerError); |     if (ItimerError != NULL) | ||||||
|  |     	PyDict_SetItemString(d, "ItimerError", ItimerError); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|         if (!PyErr_Occurred()) |         if (!PyErr_Occurred()) | ||||||
|  |  | ||||||
|  | @ -641,7 +641,10 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, | ||||||
| 	    /* We know this can't fail, since we've already
 | 	    /* We know this can't fail, since we've already
 | ||||||
| 	       reserved enough space. */ | 	       reserved enough space. */ | ||||||
| 	    STRINGLIB_CHAR *pstart = p + n_leading_chars; | 	    STRINGLIB_CHAR *pstart = p + n_leading_chars; | ||||||
| 	    int r = STRINGLIB_GROUPING(pstart, n_digits, n_digits, | #ifndef NDEBUG | ||||||
|  | 	    int r = | ||||||
|  | #endif | ||||||
|  | 		STRINGLIB_GROUPING(pstart, n_digits, n_digits, | ||||||
| 			   spec.n_total+n_grouping_chars-n_leading_chars, | 			   spec.n_total+n_grouping_chars-n_leading_chars, | ||||||
| 			   NULL, 0); | 			   NULL, 0); | ||||||
| 	    assert(r); | 	    assert(r); | ||||||
|  |  | ||||||
|  | @ -32,6 +32,8 @@ PyStructSequence_New(PyTypeObject *type) | ||||||
| 	PyStructSequence *obj; | 	PyStructSequence *obj; | ||||||
| 
 | 
 | ||||||
| 	obj = PyObject_New(PyStructSequence, type); | 	obj = PyObject_New(PyStructSequence, type); | ||||||
|  | 	if (obj == NULL) | ||||||
|  | 		return NULL; | ||||||
| 	Py_SIZE(obj) = VISIBLE_SIZE_TP(type); | 	Py_SIZE(obj) = VISIBLE_SIZE_TP(type); | ||||||
| 
 | 
 | ||||||
| 	return (PyObject*) obj; | 	return (PyObject*) obj; | ||||||
|  | @ -522,10 +524,16 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) | ||||||
| 	Py_INCREF(type); | 	Py_INCREF(type); | ||||||
| 
 | 
 | ||||||
| 	dict = type->tp_dict; | 	dict = type->tp_dict; | ||||||
| 	PyDict_SetItemString(dict, visible_length_key,  | #define SET_DICT_FROM_INT(key, value)				\ | ||||||
| 		       PyInt_FromLong((long) desc->n_in_sequence)); | 	do {							\ | ||||||
| 	PyDict_SetItemString(dict, real_length_key,  | 		PyObject *v = PyInt_FromLong((long) value);	\ | ||||||
| 		       PyInt_FromLong((long) n_members)); | 		if (v != NULL) {				\ | ||||||
| 	PyDict_SetItemString(dict, unnamed_fields_key,  | 			PyDict_SetItemString(dict, key, v);	\ | ||||||
| 		       PyInt_FromLong((long) n_unnamed_members)); | 			Py_DECREF(v);				\ | ||||||
|  | 		}						\ | ||||||
|  | 	} while (0) | ||||||
|  | 
 | ||||||
|  | 	SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence); | ||||||
|  | 	SET_DICT_FROM_INT(real_length_key, n_members); | ||||||
|  | 	SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1312,7 +1312,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
| getbuffer(PyObject *arg, Py_buffer *view, char**errmsg) | getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) | ||||||
| { | { | ||||||
| 	void *buf; | 	void *buf; | ||||||
| 	Py_ssize_t count; | 	Py_ssize_t count; | ||||||
|  | @ -1322,8 +1322,10 @@ getbuffer(PyObject *arg, Py_buffer *view, char**errmsg) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	if (pb->bf_getbuffer) { | 	if (pb->bf_getbuffer) { | ||||||
| 		if (pb->bf_getbuffer(arg, view, 0) < 0) | 		if (pb->bf_getbuffer(arg, view, 0) < 0) { | ||||||
|  | 			*errmsg = "convertible to a buffer"; | ||||||
| 			return -1; | 			return -1; | ||||||
|  | 		} | ||||||
| 		if (!PyBuffer_IsContiguous(view, 'C')) { | 		if (!PyBuffer_IsContiguous(view, 'C')) { | ||||||
| 			*errmsg = "contiguous buffer"; | 			*errmsg = "contiguous buffer"; | ||||||
| 			return -1; | 			return -1; | ||||||
|  | @ -1332,8 +1334,10 @@ getbuffer(PyObject *arg, Py_buffer *view, char**errmsg) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	count = convertbuffer(arg, &buf, errmsg); | 	count = convertbuffer(arg, &buf, errmsg); | ||||||
| 	if (count < 0) | 	if (count < 0) { | ||||||
|  | 		*errmsg = "convertible to a buffer"; | ||||||
| 		return count; | 		return count; | ||||||
|  | 	} | ||||||
| 	PyBuffer_FillInfo(view, NULL, buf, count, 1, 0); | 	PyBuffer_FillInfo(view, NULL, buf, count, 1, 0); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -132,8 +132,8 @@ Py_InitializeEx(int install_sigs) | ||||||
| 	PyThreadState *tstate; | 	PyThreadState *tstate; | ||||||
| 	PyObject *bimod, *sysmod; | 	PyObject *bimod, *sysmod; | ||||||
| 	char *p; | 	char *p; | ||||||
| 	char *icodeset; /* On Windows, input codeset may theoretically 
 | 	char *icodeset = NULL; /* On Windows, input codeset may theoretically 
 | ||||||
| 			   differ from output codeset. */ | 			          differ from output codeset. */ | ||||||
| 	char *codeset = NULL; | 	char *codeset = NULL; | ||||||
| 	char *errors = NULL; | 	char *errors = NULL; | ||||||
| 	int free_codeset = 0; | 	int free_codeset = 0; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Neal Norwitz
						Neal Norwitz