GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — sqlite3 converter lookup can crash during concurrent registry updates in free-threaded builds · Issue #155781 · python/cpython

sqlite3 converter lookup can crash during concurrent registry updates in free-threaded builds #155781

New issue
Copy link
New issue
Copy link
Closed
Closed
sqlite3 converter lookup can crash during concurrent registry updates in free-threaded builds#155781
Copy link
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtopic-free-threadingtopic-sqlite3type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or errortype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump

Description

@cuishuang
cuishuang
opened on Aug 14, 2026
Issue body actions

Bug report

Bug description:

In Modules/_sqlite/cursor.c, _pysqlite_get_converter() currently looks up a converter with:

retval = PyDict_GetItemWithError(state->converters, upcase_key);
return retval;

PyDict_GetItemWithError() returns a borrowed reference.

In a free-threaded build, another thread can replace or remove the converter after the dictionary lookup has completed but before pysqlite_build_row_cast_map() appends the converter to row_cast_map.

The converter registry can be modified either through:

sqlite3.register_converter(name, replacement)

or directly through the public sqlite3.converters dictionary.

A possible sequence is:

  1. A cursor thread obtains a borrowed converter reference.
  2. Another thread replaces or removes that dictionary entry.
  3. The previous converter is finalized.
  4. The cursor thread passes the no-longer-valid reference to PyList_Append().

A stress test on a free-threaded debug build of CPython main reproduces an interpreter crash.

The adapter registry already uses PyDict_GetItemRef() when looking up adapters. The converter lookup should similarly retain a strong reference until the converter has been added to the row cast map.

A proposed fix is to make _pysqlite_get_converter() return a new reference using PyDict_GetItemRef() and update pysqlite_build_row_cast_map() to release that reference after PyList_Append().

Reproducer

import sqlite3
import threading

NAME = "CONVERTER_RACE"
NCOLUMNS = 64
NITER = 3000

QUERY = "select " + ", ".join(
    f"'value' as 'c{i} [{NAME}]'" for i in range(NCOLUMNS)
)

class Converter:
    __slots__ = ("value",)

    def __init__(self, value):
        self.value = value

    def __call__(self, value):
        return self.value

def reader():
    con = sqlite3.connect(
        ":memory:",
        detect_types=sqlite3.PARSE_COLNAMES,
    )
    try:
        for _ in range(NITER):
            con.execute(QUERY).fetchone()
    finally:
        con.close()

def mutator():
    for i in range(NITER * NCOLUMNS):
        sqlite3.register_converter(NAME, Converter(i))
        if i % 3 == 0:
            sqlite3.converters.pop(NAME, None)

threads = [
    *[threading.Thread(target=reader) for _ in range(8)],
    *[threading.Thread(target=mutator) for _ in range(2)],
]

for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

  • gh-155781: Hold strong references to sqlite3 converters #155784
  • [3.15] gh-155781: Hold strong references to sqlite3 converters (GH-155784) #156192

Activity

  1. cuishuang
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Aug 14, 2026
  2. aisk
    added
    extension-modulesC modules in the Modules dirC modules in the Modules dir
    type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
    topic-sqlite3
    topic-free-threading
    on Aug 14, 2026
  3. github-project-automation
    added this to sqlite3 issueson Aug 14, 2026
  4. cuishuang
    added 2 commits that reference this issue on Aug 16, 2026

    pythongh-155781: Hold strong references to sqlite3 converters

    0df980d

    pythongh-155781: Hold strong references to sqlite3 converters

    88d3efe
  5. kumaraditya303
    added a commit that references this issue on Aug 21, 2026

    gh-155781: Hold strong references to sqlite3 converters (#155784)

    65e149a
  6. kumaraditya303
    closed this as completedon Aug 21, 2026
  7. github-project-automation
    moved this to Done in sqlite3 issueson Aug 21, 2026
  8. hugovk
    added a commit that references this issue on Aug 29, 2026

    [3.15] gh-155781: Hold strong references to sqlite3 converters (GH-15…

    bd519fc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirC modules in the Modules dirtopic-free-threadingtopic-sqlite3type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or errortype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump

    Projects

    • sqlite3 issues
      Status
      Done
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.