◐ Shell
clean mode source ↗

bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once by orenmn · Pull Request #3968 · python/cpython

vstinner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, except of "del ref".

@serhiy-storchaka: Would you mind to double-check this PR please?

It seems like "self->in_weakreflist" is already set to NULL by the memory allocator, so it's safe to remove "self->in_weakreflist = NULL;".

ref = weakref.ref(cur, callback)
cur.__init__(con)
del cur
del ref # shouldn't crash

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the purpose of removing explicitly the last reference to a weak reference object. Just remove "del ref" ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least on my Windows 10, when the test fails, the del ref causes the crash info that is printed to include the line (and test) that caused the crash
(i.e. File "C:\Users\orenm\cpython\lib\sqlite3\test\regression.py", line 392 in CheckBpo31770). If i remove the del ref, it doesn't show info about the line and test that caused the crash.
If you still think that i should remove it, i wouldn't mind, of course.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add test.support.gc_collect() for ensuring that objects are collected.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When i use test.support.gc_collect(), the crash info also doesn't include the line and the test that crashed.
Also, when i add 1/0 after the call to gc_collect(), and run the test (on cpython without the patch in C code), the code doesn't crash in gc_collect(), and a ZeroDivisionError is raised...
(of course, without the 1/0, it does crash, but after the gc_collect(), i guess.)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should i replace the del ref with a call to test.support.gc_collect() anyway?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you call test.support.gc_collect() instead of del ref? Or adding test.support.gc_collect() after del ref breaks the test?

I meant that you should keep del ref, but call test.support.gc_collect() after it for sure. Of course, if this breaks the test, don't add it.

@vstinner

I didn't approve the PR yet because of my question on "del ref".

@vstinner

The line number doesn't matter for a test triggering a crash, I mean non regression trst fixing a crash. Yes, replace the useless del with gc_collect() please.

@orenmn

IIUC, calling gc_collect() without doing del ref wouldn't really cause the collection of ref, because there is still one reference to it until the method is over. The call to gc_collect() is to make sure ref is collected, as Serhiy advised.
Is it ok, Victor, or am i missing something?

@miss-islington

Thanks @orenmn for the PR, and @Haypo for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request

Nov 7, 2017

@bedevere-bot

@miss-islington

Thanks @orenmn for the PR, and @Haypo for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7.
🐍🍒⛏🤖

@bedevere-bot

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request

Nov 7, 2017

vstinner pushed a commit that referenced this pull request

Nov 7, 2017

vstinner pushed a commit that referenced this pull request

Nov 7, 2017

embray pushed a commit to embray/cpython that referenced this pull request

Nov 9, 2017