New submission from Oren Milman <ore...@gmail.com>: 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. ---------- components: Extension Modules messages: 304220 nosy: Oren Milman priority: normal severity: normal status: open title: crash and refleaks when calling sqlite3.Cursor.__init__() more than once type: crash versions: Python 3.7 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue31770> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com