homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author dmalcolm
Recipients dmalcolm
Date 2013年02月14日.16:07:36
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1360858057.09.0.617835061471.issue17206@psf.upfronthosting.co.za>
In-reply-to
Content
When running my refcount static analyzer [1] on a large corpus of real-world C extension code for Python, I ran into the following construct in various places:
 Py_XDECREF(PyObject_CallObject(callable, args));
This is bogus code: Py_XDECREF expands its argument multiple times, so after this goes through the C preprocessor the callable is actually called invoked up to 4 times, leaking refs to 3 of the results - assuming that none of the calls fail, and a non pydebug build of CPython (which would expand the argument more times).
The raw preprocessor output for an optimized Python 2.7 looks like this:
 do { if ((PyObject_CallObject(callable, args)) == ((void *)0)) ; else do { if ( --((PyObject*)(PyObject_CallObject(callable, args)))->ob_refcnt != 0) ; else ( (*(((PyObject*)((PyObject *)(PyObject_CallObject(callable, args))))->ob_type)->tp_dealloc)((PyObject *)((PyObject *)(PyObject_CallObject(callable, args))))); } while (0); } while (0);
Cleaned up (and removing some of the casts for clarity) it looks like this:
 do { 
 if ((PyObject_CallObject(callable, args)) == ((void *)0))
 ; 
 else 
 do {
 if (--(PyObject_CallObject(callable, args)->ob_refcnt) != 0)
 ;
 else
 (*(PyObject_CallObject(callable, args)->ob_type)->tp_dealloc)
 PyObject_CallObject(callable, args);
 } while (0);
 } while (0);
which is clearly not what the extension author was expecting.
Should we:
 (A) update the macro so that it expands its argument only once, or
 (B) warn people not to write code like the above?
Similar considerations apply to the other macros, I guess, but I've seen the above used "in the wild", I haven't yet seen it for the other macros).
Seen in the wild in:
 python-alsa-1.0.25-1.fc17:
 pyalsa/alsamixer.c:179
 00174 | 	for (i = 0; i < count; i++) { 
 00175 | 		t = PyTuple_New(2); 
 00176 | 		if (t) { 
 00177 | 			PyTuple_SET_ITEM(t, 0, PyInt_FromLong(pfd[i].fd)); 
 00178 | 			PyTuple_SET_ITEM(t, 1, PyInt_FromLong(pfd[i].events)); 
 00179>| 			Py_XDECREF(PyObject_CallObject(reg, t)); 
 00180 | 			Py_DECREF(t); 
 00181 | 		} 
 00182 | 	}	 
 00183 | 
 00184 | 	Py_XDECREF(reg); 
 pyalsa/alsahcontrol.c:190
 00185 | 	for (i = 0; i < count; i++) { 
 00186 | 		t = PyTuple_New(2); 
 00187 | 		if (t) { 
 00188 | 			PyTuple_SET_ITEM(t, 0, PyInt_FromLong(pfd[i].fd)); 
 00189 | 			PyTuple_SET_ITEM(t, 1, PyInt_FromLong(pfd[i].events)); 
 00190>| 			Py_XDECREF(PyObject_CallObject(reg, t)); 
 00191 | 			Py_DECREF(t); 
 00192 | 		} 
 00193 | 	}	 
 00194 | 
 00195 | 	Py_XDECREF(reg); 
 pyalsa/alsaseq.c:3277
 03272 | for (i = 0; i < count; i++) { 
 03273 | t = PyTuple_New(2); 
 03274 | if (t) { 
 03275 | PyTuple_SET_ITEM(t, 0, PyInt_FromLong(pfd[i].fd)); 
 03276 | PyTuple_SET_ITEM(t, 1, PyInt_FromLong(pfd[i].events)); 
 03277>| Py_XDECREF(PyObject_CallObject(reg, t)); 
 03278 | Py_DECREF(t); 
 03279 | } 
 03280 | } 
 03281 | 
 03282 | Py_XDECREF(reg); 
 python-4Suite-XML-1.0.2-14.fc17:
 Ft/Xml/src/domlette/refcounts.c:80
 00075 | /* refcount = this */ 
 00076 | expected = 1; 
 00077 | } 
 00078 | else { 
 00079 | sprintf(buf, "Unexpected object type '%.200s'" ,node->ob_type->tp_name); 
 00080>| Py_XDECREF(PyObject_CallMethod(tester, "error", "s", buf)); 
 00081 | return 0; 
 00082 | } 
 00083 | 
 00084 | sprintf(buf, "%.200s refcounts", node->ob_type->tp_name); 
 00085 | return do_test(tester, buf, expected, node->ob_refcnt); 
[Note to self: I actually saw this because it uncovered a traceback in cpychecker, which I fixed as:
http://git.fedorahosted.org/cgit/gcc-python-plugin.git/commit/?id=99fa820487e380b74c2eda1d97facdf2ee6d2f3a ]
[1] https://gcc-python-plugin.readthedocs.org/en/latest/cpychecker.html 
History
Date User Action Args
2013年02月14日 16:07:37dmalcolmsetrecipients: + dmalcolm
2013年02月14日 16:07:37dmalcolmsetmessageid: <1360858057.09.0.617835061471.issue17206@psf.upfronthosting.co.za>
2013年02月14日 16:07:37dmalcolmlinkissue17206 messages
2013年02月14日 16:07:36dmalcolmcreate

AltStyle によって変換されたページ (->オリジナル) /