Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork34k
gh-142830: prevent some crashes when mutatingsqlite3 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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
picnixz commentedDec 28, 2025
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. |
bedevere-bot commentedDec 28, 2025
🤖 New build scheduled with the buildbot fleet by@picnixz for commit4dd0652 🤖 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. |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
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.
picnixz commentedDec 31, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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. |
picnixz commentedDec 31, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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. |
serhiy-storchaka commentedDec 31, 2025
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 |
serhiy-storchaka commentedDec 31, 2025
I do not talk what you should do, I only describe variants which may be more laconic than the current PR. |
picnixz commentedDec 31, 2025
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 (consideringevery statement would require INCREF/DECREF of the entire context, it's clearly not a good idea indeed). |
picnixz commentedDec 31, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@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 to2c1af7eCompare2c1af7e to504ef19Compare
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. 👍
Uh oh!
There was an error while loading.Please reload this page.
7f6c16a intopython:mainUh oh!
There was an error while loading.Please reload this page.
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 |
picnixz commentedJan 1, 2026
Of course backports have conflicts -_- |
…callbacks (pythonGH-143245)(cherry picked from commit7f6c16a)Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
GH-143322 is a backport of this pull request to the3.14 branch. |
…callbacks (pythonGH-143245)(cherry picked from commit7f6c16a)Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
GH-143323 is a backport of this pull request to the3.13 branch. |
Uh oh!
There was an error while loading.Please reload this page.
This isnot 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