diff --git a/ddtrace/profiling/collector/_memalloc_tb.cpp b/ddtrace/profiling/collector/_memalloc_tb.cpp index 79f47136d0a..76e3a9b716a 100644 --- a/ddtrace/profiling/collector/_memalloc_tb.cpp +++ b/ddtrace/profiling/collector/_memalloc_tb.cpp @@ -9,8 +9,6 @@ /* A string containing "" just in case we can't store the real function * or file name. */ static PyObject* unknown_name = NULL; -/* A string containing "" */ -static PyObject* empty_string = NULL; static PyObject* ddframe_class = NULL; @@ -54,13 +52,6 @@ traceback_t::init() return false; PyUnicode_InternInPlace(&unknown_name); } - - if (empty_string == NULL) { - empty_string = PyUnicode_FromString(""); - if (empty_string == NULL) - return false; - PyUnicode_InternInPlace(&empty_string); - } return true; } @@ -183,7 +174,7 @@ traceback_t::to_tuple() const PyObject* stack = PyTuple_New(frames.size()); for (size_t nframe = 0; nframe < frames.size(); nframe++) { - PyObject* frame_tuple = PyTuple_New(4); + PyObject* frame_tuple = PyTuple_New(3); const frame_t& frame = frames[nframe]; @@ -192,9 +183,6 @@ traceback_t::to_tuple() const PyTuple_SET_ITEM(frame_tuple, 1, PyLong_FromUnsignedLong(frame.lineno)); Py_INCREF(frame.name); PyTuple_SET_ITEM(frame_tuple, 2, frame.name); - /* Class name */ - Py_INCREF(empty_string); - PyTuple_SET_ITEM(frame_tuple, 3, empty_string); // Try to set the class. If we cannot (e.g., if the sofile is reloaded // without module initialization), then this will result in an error if diff --git a/ddtrace/profiling/collector/_traceback.pyx b/ddtrace/profiling/collector/_traceback.pyx index 1c9d1cb4321..1460e6d3404 100644 --- a/ddtrace/profiling/collector/_traceback.pyx +++ b/ddtrace/profiling/collector/_traceback.pyx @@ -8,31 +8,6 @@ from ddtrace.profiling.event import DDFrame log = get_logger(__name__) -cpdef _extract_class_name(frame): - # type: (...) -> str - """Extract class name from a frame, if possible. - - :param frame: The frame object. - """ - code = frame.f_code - if code.co_argcount > 0: - # Retrieve the name of the first argument, if the code object has any - argname = code.co_varnames[0] - try: - value = frame.f_locals[argname] - except Exception: - log.debug("Unable to extract class name from frame %r", frame, exc_info=True) - return "" - try: - if argname == "self": - return object.__getattribute__(type(value), "__name__") # use type() and object.__getattribute__ to avoid side-effects - if argname == "cls": - return object.__getattribute__(value, "__name__") - except AttributeError: - return "" - return "" - - cpdef pyframe_to_frames(frame, max_nframes): """Convert a Python frame to a list of frames. @@ -71,7 +46,7 @@ cpdef pyframe_to_frames(frame, max_nframes): return [], 0 lineno = 0 if frame.f_lineno is None else frame.f_lineno - frames.append(DDFrame(code.co_filename, lineno, code.co_name, _extract_class_name(frame))) + frames.append(DDFrame(code.co_filename, lineno, code.co_name)) nframes += 1 frame = frame.f_back return frames, nframes diff --git a/ddtrace/profiling/event.py b/ddtrace/profiling/event.py index 1c5bc8f379e..de5ea1f3992 100644 --- a/ddtrace/profiling/event.py +++ b/ddtrace/profiling/event.py @@ -2,5 +2,5 @@ import typing -DDFrame = namedtuple("DDFrame", ["file_name", "lineno", "function_name", "class_name"]) +DDFrame = namedtuple("DDFrame", ["file_name", "lineno", "function_name"]) StackTraceType = typing.List[DDFrame] diff --git a/releasenotes/notes/profiling-f_locals-c345ca501ca9b74f.yaml b/releasenotes/notes/profiling-f_locals-c345ca501ca9b74f.yaml new file mode 100644 index 00000000000..af4206656ef --- /dev/null +++ b/releasenotes/notes/profiling-f_locals-c345ca501ca9b74f.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + profiling: Fixes a segmentation fault caused by accessing ``frame.f_locals`` + while trying to retrieve class name of a ``PyFrameObject``.