diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2017-03-07 05:24:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-07 05:24:37 (GMT) |
commit | 93fac8dd358cd0e85e7b59115db226ce685d3f6f (patch) | |
tree | 51cab83ce4e14a779fc2f2467cab142b331e8034 /Python | |
parent | d36a71637cefdddc02efd884f1b2c204f370afaa (diff) | |
download | cpython-93fac8dd358cd0e85e7b59115db226ce685d3f6f.zip cpython-93fac8dd358cd0e85e7b59115db226ce685d3f6f.tar.gz cpython-93fac8dd358cd0e85e7b59115db226ce685d3f6f.tar.bz2 |
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.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 49177d8..e682fc1 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4818,7 +4818,20 @@ call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames) } else if (Py_TYPE(func) == &PyMethodDescr_Type) { 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 { if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) { |