mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-29676: fix lsprof can't profile C method call. (GH523)
When LOAD_METHOD is used for calling C mehtod, PyMethodDescrObject
was passed to profilefunc from 5566bbb
.
But lsprof traces only PyCFunctionObject. Additionally, there can be
some third party extension which assumes passed arg is
PyCFunctionObject without calling PyCFunction_Check().
So make PyCFunctionObject from PyMethodDescrObject when
tstate->c_profilefunc is set.
This commit is contained in:
parent
d36a71637c
commit
93fac8dd35
1 changed files with 14 additions and 1 deletions
|
@ -4818,7 +4818,20 @@ 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();
|
||||||
C_TRACE(x, _PyMethodDescr_FastCallKeywords(func, stack, nargs, kwnames));
|
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 (func == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
C_TRACE(x, _PyCFunction_FastCallKeywords(func, stack+1, nargs-1,
|
||||||
|
kwnames));
|
||||||
|
Py_DECREF(func);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = _PyMethodDescr_FastCallKeywords(func, stack, nargs, kwnames);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
|
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue