gh-142830: prevent some crashes when mutating sqlite3 callbacks#143245
gh-142830: prevent some crashes when mutating sqlite3 callbacks#143245picnixz merged 10 commits intopython:mainfrom
sqlite3 callbacks#143245Conversation
|
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.
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 |
18c4f54 to
2c1af7e
Compare
2c1af7e to
504ef19
Compare
|
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. |
|
Earlier we relied on GC for these callbacks; IOW, we did not use the SQLite C API provided destructor machinery. Perhaps we should revert to that again. It is more verbose, but it's less hacky than what the current solution has grown to be. |
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