-
Notifications
You must be signed in to change notification settings - Fork 457
fix(profiler): indirectly access frame objects for tracebacks for Python 3.11 #4895
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a73455a
to
afb2b8e
Compare
afb2b8e
to
3bd4a59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@P403n1x87 At first glance it looks like it's only the _traceback.pyx
module that works with PyFrameObjects, but to be fair this is the only obvious fix relating to Python 3.11. Would love your feedback/second look 🙇
ec59155
to
7bc7816
Compare
cb63bdd
to
d5eb8c6
Compare
d5eb8c6
to
0004bd1
Compare
lineno = PyFrame_GetLineNumber(<PyFrameObject*> frame) | ||
lineno = 0 if lineno is None else lineno | ||
frames.append(((<object>code).co_filename, lineno, (<object>code).co_name, _extract_class_name(frame))) | ||
frame = <object>PyFrame_GetBack(<PyFrameObject*> frame) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PyFrame_GetBack()
returns a strong reference. Should I be calling Py_XDECREF(frame)
even though we are iterating through these references?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the frame isn't actually needed anymore after L114 right? since we are creating/returning a list of tuples?
does the frame getting GC'd cause co_filename/co_name/etc to also get GC'd? are we appropriately incref/decref-ing those references?
releasenotes/notes/profiler-3-11-traceback-fix-4c98c3ce96833df6.yaml
Outdated
Show resolved
Hide resolved
frames.append(((<object>code).co_filename, lineno, (<object>code).co_name, _extract_class_name(<object>pyframe))) | ||
Py_XDECREF(<PyObject*>code) | ||
pyframe = PyFrame_GetBack(pyframe) | ||
# FIXME: Where to Py_XDECREF(cframe)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/cframe/pyframe/
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the catch!
I am looking for some suggestions on where to call Py_XDECREF(pyframe)
though. Since PyFrame_GetBack(pyframe)
returns a strong reference of the PyFrameObject*
, should I be decrementing the refcount for every time we call PyFrame_GetBack(pyframe)
? But since we're using the result of the PyFrame_GetBack()
in the while loop, I don't think I can decrement the refcount without interfering with the rest of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Py_XDECREF(pyframe)
has to be called every time you are done with that particular pyframe
reference, so within the loop, but before overwriting the variable's value. The cast to <object>
is taking care of ref counting when passing values around in Cython, so as long as our ref counting for when we invoke the C API directly is correct we should be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you might need to do something like:
cdef PyFrameObject* cur_frame = pyframe
pyframe = PyFrame_GetBack(cur_frame)
Py_XDECREF(cur_frame)
? and then a final Py_XDECREF(pyframe)
after the while ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes sense. Trying that now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have thought that
Py_XDECREF(pyframe)
pyframe = PyFrame_GetBack(pyframe)
is enough, since we are manipulating Python objects and hence we're holding the GIL. But @brettlangdon's suggestion works too.
d5b0a33
to
0f9e710
Compare
Currently running into a segmentation fault after adding the |
…ect (#4952) ## Description As #4895 has not been merged yet and we don't want to block the 1.8 release any longer, this PR adds a release note entry publishing the known issue of the profiler running in Python 3.11 with the new `PyFrameObject` opaque struct changes. <!-- If this is a breaking change, explain why it is necessary. Breaking changes must append `!` after the type/scope. See https://ddtrace.readthedocs.io/en/stable/contributing.html for more details. --> ## Checklist - [ ] Followed the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) when writing a release note. - [ ] Add additional sections for `feat` and `fix` pull requests. - [ ] [Library documentation](https://github.com/DataDog/dd-trace-py/tree/1.x/docs) and/or [Datadog's documentation site](https://github.com/DataDog/documentation/) is updated. Link to doc PR in description. <!-- Copy and paste the relevant snippet based on the type of pull request --> <!-- START feat --> ## Motivation <!-- Expand on why the change is required, include relevant context for reviewers --> ## Design <!-- Include benefits from the change as well as possible drawbacks and trade-offs --> ## Testing strategy <!-- Describe the automated tests and/or the steps for manual testing. <!-- END feat --> <!-- START fix --> ## Relevant issue(s) <!-- Link the pull request to any issues related to the fix. Use keywords for links to automate closing the issues once the pull request is merged. --> ## Testing strategy <!-- Describe any added regression tests and/or the manual testing performed. --> <!-- END fix --> ## Reviewer Checklist - [ ] Title is accurate. - [ ] Description motivates each change. - [ ] No unnecessary changes were introduced in this PR. - [ ] Avoid breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [ ] Tests provided or description of manual testing performed is included in the code or PR. - [ ] Release note has been added and follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines), or else `changelog/no-changelog` label added. - [ ] All relevant GitHub issues are correctly linked. - [ ] Change contains telemetry where appropriate (logs, metrics, etc.). - [ ] Telemetry is meaningful, actionable and does not have the potential to leak sensitive data.
…ect (#4952) ## Description As #4895 has not been merged yet and we don't want to block the 1.8 release any longer, this PR adds a release note entry publishing the known issue of the profiler running in Python 3.11 with the new `PyFrameObject` opaque struct changes. <!-- If this is a breaking change, explain why it is necessary. Breaking changes must append `!` after the type/scope. See https://ddtrace.readthedocs.io/en/stable/contributing.html for more details. --> ## Checklist - [ ] Followed the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) when writing a release note. - [ ] Add additional sections for `feat` and `fix` pull requests. - [ ] [Library documentation](https://github.com/DataDog/dd-trace-py/tree/1.x/docs) and/or [Datadog's documentation site](https://github.com/DataDog/documentation/) is updated. Link to doc PR in description. <!-- Copy and paste the relevant snippet based on the type of pull request --> <!-- START feat --> ## Motivation <!-- Expand on why the change is required, include relevant context for reviewers --> ## Design <!-- Include benefits from the change as well as possible drawbacks and trade-offs --> ## Testing strategy <!-- Describe the automated tests and/or the steps for manual testing. <!-- END feat --> <!-- START fix --> ## Relevant issue(s) <!-- Link the pull request to any issues related to the fix. Use keywords for links to automate closing the issues once the pull request is merged. --> ## Testing strategy <!-- Describe any added regression tests and/or the manual testing performed. --> <!-- END fix --> ## Reviewer Checklist - [ ] Title is accurate. - [ ] Description motivates each change. - [ ] No unnecessary changes were introduced in this PR. - [ ] Avoid breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [ ] Tests provided or description of manual testing performed is included in the code or PR. - [ ] Release note has been added and follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines), or else `changelog/no-changelog` label added. - [ ] All relevant GitHub issues are correctly linked. - [ ] Change contains telemetry where appropriate (logs, metrics, etc.). - [ ] Telemetry is meaningful, actionable and does not have the potential to leak sensitive data.
@P403n1x87 Closing this PR until we can confirm that the issue persists after #5019, in which case I'll reopen this. |
Description
#4511 added support for Python 3.11 for the profiler, but missed some
PyFrameObject
-related upgrades required to be compatible with Python 3.11, most notably in the stack collector's traceback module. Specifically,PyFrameObjects
and its member values are now lazily created/computed, which means we can no longer directly access its member values.According to https://docs.python.org/3/whatsnew/3.11.html#pyframeobject-3-11-hiding, we need to use get functions to access its member values.
Checklist
feat
andfix
pull requests.Motivation
Design
Testing strategy
Relevant issue(s)
Testing strategy
Reviewer Checklist
changelog/no-changelog
label added.