Skip to content

test_free_threading.test_dict on TSAN/free-threading is flaky #130519

Description

@picnixz

Bug report

Bug description:

We have:

0:04:15 load avg: 7.63 [20/23/2] test_free_threading worker non-zero exit code (Exit code -6 (SIGABRT)) -- running (2): test_socket (1 min 38 sec), test_threading (38.8 sec)
python: Objects/obmalloc.c:1219: void process_queue(struct llist_node *, struct _qsbr_thread_state *, _Bool, delayed_dealloc_cb, void *): Assertion `buf->rd_idx == buf->wr_idx' failed.
Fatal Python error: Aborted

<Cannot show all threads while the GIL is disabled>
Stack (most recent call first):
  File "/home/runner/work/cpython/cpython/Lib/test/test_free_threading/test_dict.py", line 184 in writer_func
  File "/home/runner/work/cpython/cpython/Lib/threading.py", line 996 in run
  File "/home/runner/work/cpython/cpython/Lib/threading.py", line 1054 in _bootstrap_inner
  File "/home/runner/work/cpython/cpython/Lib/threading.py", line 1016 in _bootstrap

Extension modules: _testinternalcapi, _testcapi (total: 2)

I'm not sure if it's a real bug or not. Victor suggested me to open an issue for this one. Maybe there's already one that exists though.

See https://github.com/python/cpython/actions/runs/13225352402/job/36915529351?pr=129175#step:12:44 for the log (hopefully it will stay).

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

Activity

  1. sergey-miryanov commented on Feb 24, 2025

    @sergey-miryanov
    Contributor

    I'm a bit stuck with my last PR. Do you want me to look into this?

  2. picnixz commented on Feb 24, 2025

    @picnixz
    MemberAuthor

    You can investigate if you want but maybe free-threading experts have an idea of why it fails.

    cc @ZeroIntensity maybe you've encountered this beforehand?

  3. ZeroIntensity commented on Feb 24, 2025

    @ZeroIntensity
    Member

    I haven't seen it. I think there's a thread somewhere where you're supposed to report flaky TSan failures.

  4. colesbury commented on Feb 25, 2025

    @colesbury
    Contributor

    This is a good place to report it, thanks.

    I think the problem is that free_work_item can be re-entrant because it calls Py_DECREF(). Originally, the QSBR code just made calls to PyMem_Free() or PyObject_Free(), which are never re-entrant. In:

    We extended it to also executing Py_DECREF() on objects, which can execute arbitrary code via destructors, including re-entering QSBR (possibly during a GC).

    This invalidates some assumptions. For example, the head of the work queue can change during a call to free_work_item:

    cpython/Objects/obmalloc.c

    Lines 1258 to 1268 in c5f925c

    struct _mem_work_chunk *buf = work_queue_first(head);
    while (buf->rd_idx < buf->wr_idx) {
    struct _mem_work_item *item = &buf->array[buf->rd_idx];
    if (!_Py_qsbr_poll(qsbr, item->qsbr_goal)) {
    return;
    }
    free_work_item(item->ptr, cb, state);
    buf->rd_idx++;
    }

    cc @DinoV

  5. self-assigned this
    on Feb 25, 2025
  6. added 4 commits that reference this issue on Feb 25, 2025
  7. colesbury commented on Mar 2, 2025

    @colesbury
    Contributor

    This should be fixed now.

  8. added 3 commits that reference this issue on May 27, 2025
  9. added a commit that references this issue on May 27, 2025
  10. added a commit that references this issue on May 27, 2025
  11. added a commit that references this issue on Jul 12, 2025
  12. added a commit that references this issue on Aug 4, 2025
  13. added a commit that references this issue on Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)testsTests in the Lib/test dirtopic-free-threadingtype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions