mirror of https://github.com/python/cpython
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:
parent
09c0178242
commit
b2d61bde28
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue