Skip to content

Commit 0f9e710

Browse files
committed
Add Py_XDECREF for _extract_class_name, cast code as <object>
1 parent 7ad29b7 commit 0f9e710

File tree

2 files changed

+14
-11
lines changed

2 files changed

+14
-11
lines changed

ddtrace/profiling/collector/_traceback.pyx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ cpdef _extract_class_name(frame):
2727
"""
2828
# Python 3.11 moved PyFrameObject members to internal C API and cannot be directly accessed
2929
IF PY_MAJOR_VERSION > 3 or (PY_MAJOR_VERSION == 3 and PY_MINOR_VERSION >= 11):
30-
code = PyFrame_GetCode(<PyFrameObject*>frame)
31-
co_varnames = PyCode_GetVarnames(code)
32-
if PyTuple_Size(co_varnames) == 0:
30+
code = PyFrame_GetCode(<PyFrameObject*>frame) # Returns strong reference
31+
co_varnames = PyCode_GetVarnames(code) # Returns new reference
32+
if co_varnames == NULL or PyTuple_Size(co_varnames) == 0:
33+
Py_XDECREF(<PyObject*>code)
3334
return ""
3435
argname = PyTuple_GetItem(co_varnames, 0)
36+
Py_XDECREF(<PyObject*>code)
37+
Py_XDECREF(co_varnames)
3538
try:
36-
f_locals = PyFrame_GetLocals(<PyFrameObject*>frame)
39+
f_locals = PyFrame_GetLocals(<PyFrameObject*>frame) # Returns strong reference
3740
value = PyDict_GetItem(f_locals, argname)
41+
Py_XDECREF(f_locals)
3842
except KeyError:
3943
return ""
4044
ELSE:
@@ -71,10 +75,10 @@ cpdef traceback_to_frames(traceback, max_nframes):
7175
frame = tb.tb_frame
7276
# Python 3.11 moved PyFrameObject members to internal C API and cannot be directly accessed
7377
IF PY_MAJOR_VERSION > 3 or (PY_MAJOR_VERSION == 3 and PY_MINOR_VERSION >= 11):
74-
code = PyFrame_GetCode(<PyFrameObject*> frame)
78+
code = <object>PyFrame_GetCode(<PyFrameObject*> frame)
7579
lineno = PyFrame_GetLineNumber(<PyFrameObject*> frame)
7680
lineno = 0 if lineno is None else lineno
77-
frames.insert(0, ((<object>code).co_filename, lineno, (<object>code).co_name, _extract_class_name(frame)))
81+
frames.insert(0, (code.co_filename, lineno, code.co_name, _extract_class_name(frame)))
7882
Py_XDECREF(<PyObject*>code)
7983
ELSE:
8084
code = frame.f_code
@@ -99,11 +103,10 @@ cpdef pyframe_to_frames(frame, max_nframes):
99103
while pyframe != NULL:
100104
nframes += 1
101105
if len(frames) < max_nframes:
102-
code = PyFrame_GetCode(pyframe)
106+
code = <object>PyFrame_GetCode(pyframe)
103107
lineno = PyFrame_GetLineNumber(pyframe)
104108
lineno = 0 if lineno is None else lineno
105-
frames.append(((<object>code).co_filename, lineno, (<object>code).co_name, _extract_class_name(<object>pyframe)))
106-
Py_XDECREF(<PyObject*>code)
109+
frames.append((code.co_filename, lineno, code.co_name, _extract_class_name(<object>pyframe)))
107110
pyframe = PyFrame_GetBack(pyframe)
108111
# FIXME: Where to Py_XDECREF(pyframe)?
109112
ELSE:
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
22
fixes:
33
- |
4-
profiling: This fix resolves an issue in where the stack collector did not properly access PyFrameObject
5-
member values, as PyFrameObject is now created and computed lazily in Python 3.11.
4+
profiling: This fix resolves a profiler compatibility issue with Python 3.11 in where the stack collector did not
5+
properly access PyFrameObject member values, as PyFrameObject is now created and computed lazily in Python 3.11.

0 commit comments

Comments
 (0)