mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +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 | ||||
|     else: | ||||
|         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) | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,6 +12,14 @@ What's New in Python 2.6 release candidate 1? | |||
| 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 | ||||
|   in order to silence a compilier warning on 64bit OSes. | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,6 +46,39 @@ | |||
| #    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) | ||||
|    Memcheck:Leak | ||||
|  |  | |||
|  | @ -416,6 +416,7 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) | |||
| 		ffi_ofs = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	assert(stgdict->format == NULL); | ||||
| 	if (isStruct && !isPacked) { | ||||
| 		stgdict->format = alloc_format_string(NULL, "T{"); | ||||
| 	} else { | ||||
|  | @ -539,7 +540,9 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) | |||
| #undef realdict | ||||
| 
 | ||||
| 	if (isStruct && !isPacked) { | ||||
| 		char *ptr = stgdict->format; | ||||
| 		stgdict->format = alloc_format_string(stgdict->format, "}"); | ||||
| 		PyMem_Free(ptr); | ||||
| 		if (stgdict->format == NULL) | ||||
| 			return -1; | ||||
| 	} | ||||
|  |  | |||
|  | @ -278,6 +278,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) | |||
| 	ret = -1; | ||||
| 
 | ||||
|  done: | ||||
| 	PyMem_Free(name); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -784,7 +784,8 @@ initsignal(void) | |||
| #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) | ||||
|     ItimerError = PyErr_NewException("signal.ItimerError",  | ||||
|          PyExc_IOError, NULL); | ||||
|     PyDict_SetItemString(d, "ItimerError", ItimerError); | ||||
|     if (ItimerError != NULL) | ||||
|     	PyDict_SetItemString(d, "ItimerError", ItimerError); | ||||
| #endif | ||||
| 
 | ||||
|         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
 | ||||
| 	       reserved enough space. */ | ||||
| 	    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, | ||||
| 			   NULL, 0); | ||||
| 	    assert(r); | ||||
|  |  | |||
|  | @ -32,6 +32,8 @@ PyStructSequence_New(PyTypeObject *type) | |||
| 	PyStructSequence *obj; | ||||
| 
 | ||||
| 	obj = PyObject_New(PyStructSequence, type); | ||||
| 	if (obj == NULL) | ||||
| 		return NULL; | ||||
| 	Py_SIZE(obj) = VISIBLE_SIZE_TP(type); | ||||
| 
 | ||||
| 	return (PyObject*) obj; | ||||
|  | @ -522,10 +524,16 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) | |||
| 	Py_INCREF(type); | ||||
| 
 | ||||
| 	dict = type->tp_dict; | ||||
| 	PyDict_SetItemString(dict, visible_length_key,  | ||||
| 		       PyInt_FromLong((long) desc->n_in_sequence)); | ||||
| 	PyDict_SetItemString(dict, real_length_key,  | ||||
| 		       PyInt_FromLong((long) n_members)); | ||||
| 	PyDict_SetItemString(dict, unnamed_fields_key,  | ||||
| 		       PyInt_FromLong((long) n_unnamed_members)); | ||||
| #define SET_DICT_FROM_INT(key, value)				\ | ||||
| 	do {							\ | ||||
| 		PyObject *v = PyInt_FromLong((long) value);	\ | ||||
| 		if (v != NULL) {				\ | ||||
| 			PyDict_SetItemString(dict, key, v);	\ | ||||
| 			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 | ||||
| getbuffer(PyObject *arg, Py_buffer *view, char**errmsg) | ||||
| getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) | ||||
| { | ||||
| 	void *buf; | ||||
| 	Py_ssize_t count; | ||||
|  | @ -1322,8 +1322,10 @@ getbuffer(PyObject *arg, Py_buffer *view, char**errmsg) | |||
| 		return -1; | ||||
| 	} | ||||
| 	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; | ||||
| 		} | ||||
| 		if (!PyBuffer_IsContiguous(view, 'C')) { | ||||
| 			*errmsg = "contiguous buffer"; | ||||
| 			return -1; | ||||
|  | @ -1332,8 +1334,10 @@ getbuffer(PyObject *arg, Py_buffer *view, char**errmsg) | |||
| 	} | ||||
| 
 | ||||
| 	count = convertbuffer(arg, &buf, errmsg); | ||||
| 	if (count < 0) | ||||
| 	if (count < 0) { | ||||
| 		*errmsg = "convertible to a buffer"; | ||||
| 		return count; | ||||
| 	} | ||||
| 	PyBuffer_FillInfo(view, NULL, buf, count, 1, 0); | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -132,8 +132,8 @@ Py_InitializeEx(int install_sigs) | |||
| 	PyThreadState *tstate; | ||||
| 	PyObject *bimod, *sysmod; | ||||
| 	char *p; | ||||
| 	char *icodeset; /* On Windows, input codeset may theoretically 
 | ||||
| 			   differ from output codeset. */ | ||||
| 	char *icodeset = NULL; /* On Windows, input codeset may theoretically 
 | ||||
| 			          differ from output codeset. */ | ||||
| 	char *codeset = NULL; | ||||
| 	char *errors = NULL; | ||||
| 	int free_codeset = 0; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Neal Norwitz
						Neal Norwitz