]> granicus.if.org Git - python/commitdiff
bpo-34126: Fix crashes while profiling invalid calls. (GH-8300)
authorjdemeyer <jdemeyer@cage.ugent.be>
Sat, 21 Jul 2018 08:30:59 +0000 (10:30 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 21 Jul 2018 08:30:59 +0000 (11:30 +0300)
Lib/test/test_sys_setprofile.py
Misc/NEWS.d/next/Core and Builtins/2018-07-16-20-55-29.bpo-34126.mBVmgc.rst [new file with mode: 0644]
Python/ceval.c

index a3e1d31fbebe94982c06dcc569409b245cb0cfed..16467e7f7184fcebab19c5789e4eaaff1155bd6a 100644 (file)
@@ -334,6 +334,22 @@ class ProfileSimulatorTestCase(TestCaseBase):
                               (1, 'return', j_ident),
                               ])
 
+    # Test an invalid call (bpo-34126)
+    def test_unbound_method_no_args(self):
+        def f(p):
+            dict.get()
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident)])
+
+    # Test an invalid call (bpo-34126)
+    def test_unbound_method_invalid_args(self):
+        def f(p):
+            dict.get(print, 42)
+        f_ident = ident(f)
+        self.check_events(f, [(1, 'call', f_ident),
+                              (1, 'return', f_ident)])
+
 
 def ident(function):
     if hasattr(function, "f_code"):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-16-20-55-29.bpo-34126.mBVmgc.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-16-20-55-29.bpo-34126.mBVmgc.rst
new file mode 100644 (file)
index 0000000..7cfc439
--- /dev/null
@@ -0,0 +1,2 @@
+Fix crashes when profiling certain invalid calls of unbound methods.
+Patch by Jeroen Demeyer.
index 90ad591dcd8f2c4c522b350bbdac703edaff1499..465e03012a3fd029ef958bab22a1d4308d9454f9 100644 (file)
@@ -4566,10 +4566,16 @@ call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
     }
     else if (Py_TYPE(func) == &PyMethodDescr_Type) {
         PyThreadState *tstate = PyThreadState_GET();
-        if (tstate->use_tracing && tstate->c_profilefunc) {
-            // We need to create PyCFunctionObject for tracing.
-            PyMethodDescrObject *descr = (PyMethodDescrObject*)func;
-            func = PyCFunction_NewEx(descr->d_method, stack[0], NULL);
+        if (nargs > 0 && tstate->use_tracing) {
+            /* We need to create a temporary bound method as argument
+               for profiling.
+
+               If nargs == 0, then this cannot work because we have no
+               "self". In any case, the call itself would raise
+               TypeError (foo needs an argument), so we just skip
+               profiling. */
+            PyObject *self = stack[0];
+            func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self));
             if (func == NULL) {
                 return NULL;
             }