Created on 2017-10-12 08:18 by Oren Milman, last changed 2017-11-07 00:50 by vstinner. This issue is now closed.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 3968 | merged | Oren Milman, 2017-10-12 16:26 | |
| PR 4301 | merged | python-dev, 2017-11-07 00:02 | |
| PR 4302 | merged | python-dev, 2017-11-07 00:03 | |
| Messages (5) | |||
|---|---|---|---|
| msg304220 - (view) | Author: Oren Milman (Oren Milman) * | Date: 2017-10-12 08:18 | |
The following code crashes:
import sqlite3
import weakref
def callback(*args):
pass
connection = sqlite3.connect(":memory:")
cursor = sqlite3.Cursor(connection)
ref = weakref.ref(cursor, callback)
cursor.__init__(connection)
del cursor
del ref
IIUC, this is because pysqlite_cursor_init() (in Modules/_sqlite/cursor.c) sets
`self->in_weakreflist` to NULL, and thus corrupts the weakref list. Later,
clear_weakref() (in Objects/weakrefobject.c) tries to remove a reference from
the corrupted list, and crashes.
In every other place (that i saw) where such a weakreflist field is used, it is
set to NULL right after allocating the object (usually in __new__()), or just
not set at all, e.g. in `functools.partial`.
So since PyType_GenericNew() is the __new__() of sqlite3.Cursor, ISTM that the
simplest solution is to not touch `self->in_weakreflist` at all in
pysqlite_cursor_init().
Also, the following code results in refleaks:
import sys
import sqlite3
connection = sqlite3.connect(":memory:")
cursor = sqlite3.Cursor(connection)
refcount_before = sys.gettotalrefcount()
cursor.__init__(connection)
print(sys.gettotalrefcount() - refcount_before) # should be close to 0
This is because pysqlite_cursor_init() doesn't decref before assigning to
fields of `self`.
I would open a PR to fix this soon.
|
|||
| msg305692 - (view) | Author: STINNER Victor (vstinner) * | Date: 2017-11-07 00:01 | |
New changeset e56ab746a965277ffcc4396d8a0902b6e072d049 by Victor Stinner (Oren Milman) in branch 'master': bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (#3968) https://github.com/python/cpython/commit/e56ab746a965277ffcc4396d8a0902b6e072d049 |
|||
| msg305698 - (view) | Author: STINNER Victor (vstinner) * | Date: 2017-11-07 00:44 | |
New changeset 4b544aadd54fd2337d2ab5c137389cae8d1fd781 by Victor Stinner (Miss Islington (bot)) in branch '2.7': bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4302) https://github.com/python/cpython/commit/4b544aadd54fd2337d2ab5c137389cae8d1fd781 |
|||
| msg305699 - (view) | Author: STINNER Victor (vstinner) * | Date: 2017-11-07 00:44 | |
New changeset 9684cf69e32ae442c7be54521073ac78557f3bbf by Victor Stinner (Miss Islington (bot)) in branch '3.6': bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4301) https://github.com/python/cpython/commit/9684cf69e32ae442c7be54521073ac78557f3bbf |
|||
| msg305700 - (view) | Author: STINNER Victor (vstinner) * | Date: 2017-11-07 00:45 | |
Thank you Oren Milman for your bug report and the bug fix! I merged your PR and backported it Python 3.6 and 2.7. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2017-11-07 00:50:12 | vstinner | set | status: open -> closed resolution: fixed stage: patch review -> resolved |
| 2017-11-07 00:45:03 | vstinner | set | messages:
+ msg305700 versions: + Python 2.7, Python 3.6 |
| 2017-11-07 00:44:25 | vstinner | set | messages: + msg305699 |
| 2017-11-07 00:44:21 | vstinner | set | messages: + msg305698 |
| 2017-11-07 00:03:45 | python-dev | set | pull_requests: + pull_request4265 |
| 2017-11-07 00:02:46 | python-dev | set | pull_requests: + pull_request4264 |
| 2017-11-07 00:01:48 | vstinner | set | messages: + msg305692 |
| 2017-10-12 16:26:25 | Oren Milman | set | keywords:
+ patch stage: patch review pull_requests: + pull_request3946 |
| 2017-10-12 08:37:26 | vstinner | set | nosy:
+ vstinner |
| 2017-10-12 08:18:36 | Oren Milman | create | |