-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
gh-142830: prevent some crashes when mutating sqlite3 callbacks
#143245
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
gh-142830: prevent some crashes when mutating sqlite3 callbacks
#143245
Conversation
|
Actually, I'm a bit worried about backporting the change to 3.13 and 3.14 because we are now using a real heap type. |
|
🤖 New build scheduled with the buildbot fleet by @picnixz for commit 4dd0652 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F143245%2Fmerge If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again. |
serhiy-storchaka
left a comment
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 can be resolved with smaller changes.
a) Just add a refcounter to the context struct. Increment and decrement it for use, and free the struct when it is 0. This is just a field and two macros or functions.
b) Save strong references to what you need in local variables just after getting the context.
|
Mmh yes, that would aloow me to backport this and avoid burdening the GC. I didn't consider this approach as I am more used to rely on existing mechanisms. I think I will add some macros or functions for holding the refs when needed. |
… `PyObject *`" This reverts commit c2f25b5.
|
So I've tried, but I miserably failed. Each callback creates a shared callback context that is either freed when the connection dies or when it got replaced. The problem is when I replace a callback:
Maybe I got it wrong or understood the mechanism wrongly, but relying on the GC is much more easier. |
|
When the callback is added, set its refcount to 1. If it is replaced, decrement its refcount. When the callback is called, increment its refcount (so that it doesn't disappear from under our feet), after calling it, decrement its refcount. If after any decrement it becomes 0, free it. This is very similar to how refcounts work for PyObject, but We don't need PyTypeObject and other boilerplate. Other way is just make local strong references to |
|
I do not talk what you should do, I only describe variants which may be more laconic than the current PR. |
|
I actually tried this initial approach but I thought "why not just rely on the GC" and then went with a full-fledged PyObject. Using a PyObject definitely makes my life easier as it's not me who's responsible for that but it's also fine to use another strategy that doesn't need this overhead (considering every statement would require INCREF/DECREF of the entire context, it's clearly not a good idea indeed). |
|
@serhiy-storchaka Thanks for the guidance! it's a bit annoying to do the manual refcounting and someone could easily forget to do it, but it's definitely better for the diff. I can also backport this PR with more confidence. |
18c4f54 to
2c1af7e
Compare
2c1af7e to
504ef19
Compare
serhiy-storchaka
left a comment
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.
LGTM. 👍
|
Thanks @picnixz for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14. |
|
Sorry, @picnixz, I could not cleanly backport this to |
|
Sorry, @picnixz, I could not cleanly backport this to |
|
Of course backports have conflicts -_- |
…callbacks (pythonGH-143245) (cherry picked from commit 7f6c16a) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
|
GH-143322 is a backport of this pull request to the 3.14 branch. |
…callbacks (pythonGH-143245) (cherry picked from commit 7f6c16a) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
|
GH-143323 is a backport of this pull request to the 3.13 branch. |
This is not a complete fix because there are other callbacks that need to be tested. I could technically split the PR into two but I preferred testing the conversion to
PyObject *in the same PR.sqlite3progress handler via re-entrant__bool__#142830