The _lsprof module could crash the interpreter if it was given an external

timer that did not return a float and a timer was still running when the
Profiler object was garbage collected.

Fixes issue 3895.
Code review by Benjamin Peterson.
This commit is contained in:
Brett Cannon 2008-09-29 03:41:21 +00:00
parent 09c0178242
commit b2d61bde28
3 changed files with 29 additions and 2 deletions

View File

@ -1,7 +1,7 @@
"""Test suite for the cProfile module."""
import sys
from test.test_support import run_unittest
from test.test_support import run_unittest, TESTFN, unlink
# rip off all interesting stuff from test_profile
import cProfile
@ -10,6 +10,20 @@ from test.test_profile import ProfileTest, regenerate_expected_output
class CProfileTest(ProfileTest):
profilerclass = cProfile.Profile
# Issue 3895.
def test_bad_counter_during_dealloc(self):
import _lsprof
# Must use a file as StringIO doesn't trigger the bug.
sys.stderr = open(TESTFN, 'w')
try:
obj = _lsprof.Profiler(lambda: int)
obj.enable()
obj = _lsprof.Profiler(1)
obj.disable()
finally:
sys.stderr = sys.__stderr__
unlink(TESTFN)
def test_main():
run_unittest(CProfileTest)

View File

@ -23,6 +23,10 @@ Core and Builtins
Library
-------
- Issue #3895: It was possible to crash the interpreter when an external timer
was used with cProfile that returned an object that could not be converted
into a float.
- Issue #3950: Made turtle respect scale factors.
- Issue #3547: Fixed ctypes structures bitfields of varying integer

View File

@ -150,7 +150,16 @@ static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj)
}
Py_DECREF(o);
if (PyErr_Occurred()) {
PyErr_WriteUnraisable((PyObject *) pObj);
PyObject *context = (PyObject *)pObj;
/* May have been called by profiler_dealloc(). */
if (Py_REFCNT(context) < 1) {
context = PyString_FromString("profiler calling an "
"external timer");
if (context == NULL) {
return 0;
}
}
PyErr_WriteUnraisable(context);
return 0;
}
return result;