]> granicus.if.org Git - python/commitdiff
The _lsprof module could crash the interpreter if it was given an external
authorBrett Cannon <bcannon@gmail.com>
Mon, 29 Sep 2008 03:41:21 +0000 (03:41 +0000)
committerBrett Cannon <bcannon@gmail.com>
Mon, 29 Sep 2008 03:41:21 +0000 (03:41 +0000)
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.

Lib/test/test_cprofile.py
Misc/NEWS
Modules/_lsprof.c

index 7ed6cec2299be05519e75206567515a3d189fb0b..13c1060118e5708cc716e1581dacd87cc397d880 100755 (executable)
@@ -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)
index 97fa2b7e3fe8bde69f91d2d0df9c3796a07d73bc..466160f67ee84bd068bfde05dcf80e996b5cc7b0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
index 5d18c3370dfb035d5968ff2b74508c279d16cd62..41c477e388c21571eb8af4ec7d8d2324b66f1a41 100644 (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;