mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
bpo-34126: Fix crashes while profiling invalid calls. (GH-8300)
This commit is contained in:
parent
a692efe473
commit
56868f940e
3 changed files with 28 additions and 4 deletions
|
@ -334,6 +334,22 @@ class ProfileSimulatorTestCase(TestCaseBase):
|
||||||
(1, 'return', j_ident),
|
(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):
|
def ident(function):
|
||||||
if hasattr(function, "f_code"):
|
if hasattr(function, "f_code"):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crashes when profiling certain invalid calls of unbound methods.
|
||||||
|
Patch by Jeroen Demeyer.
|
|
@ -4566,10 +4566,16 @@ call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
|
||||||
}
|
}
|
||||||
else if (Py_TYPE(func) == &PyMethodDescr_Type) {
|
else if (Py_TYPE(func) == &PyMethodDescr_Type) {
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = PyThreadState_GET();
|
||||||
if (tstate->use_tracing && tstate->c_profilefunc) {
|
if (nargs > 0 && tstate->use_tracing) {
|
||||||
// We need to create PyCFunctionObject for tracing.
|
/* We need to create a temporary bound method as argument
|
||||||
PyMethodDescrObject *descr = (PyMethodDescrObject*)func;
|
for profiling.
|
||||||
func = PyCFunction_NewEx(descr->d_method, stack[0], NULL);
|
|
||||||
|
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) {
|
if (func == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue