Skip to content

test_io failed with ASAN failures (heap-use-after-free) on AMD64 Arch Linux Asan 3.13 #154175

Closed

Description

@vstinner

AMD64 Arch Linux Asan 3.13: https://buildbot.python.org/#/builders/1464/builds/1125

== CPython 3.13.14+ (heads/3.13:303d0acfcdcc, Jul 19 2026, 12:37:17) [GCC 16.1.1 20260625]
== Linux-7.0.14-arch1-1-x86_64-with-glibc2.43 little-endian
== Python build: release ASAN
== cwd: /buildbot/buildarea/3.13.pablogsal-arch-x86_64.asan/build/build/test_python_worker_1123020æ
== CPU count: 2
== encodings: locale=UTF-8 FS=utf-8
== resources: all,-network,-urlfetch
== sanitizers: address
== ASAN_OPTIONS='detect_leaks=0:allocator_may_return_null=1:handle_segv=0'

(...)

FAIL: test_daemon_threads_shutdown_stderr_deadlock (test.test_io.CMiscIOTest.test_daemon_threads_shutdown_stderr_deadlock)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/buildbot/buildarea/3.13.pablogsal-arch-x86_64.asan/build/Lib/test/test_io.py", line 4755, in test_daemon_threads_shutdown_stderr_deadlock
    self.check_daemon_threads_shutdown_deadlock('stderr')
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/buildbot/buildarea/3.13.pablogsal-arch-x86_64.asan/build/Lib/test/test_io.py", line 4745, in check_daemon_threads_shutdown_deadlock
    self.assertFalse(err.strip('.!'))
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
AssertionError: '=================================================================\n
==1136209==ERROR: AddressSanitizer: heap-use-after-free on address 0x7c9453c52a58 at pc 0x555f594278c6 bp 0x7b64519fe080 sp 0x7b64519fe070\n
READ of size 8 at 0x7c9453c52a58 thread T1\n
' is not false

It seems like the test fails randomly since July 14.

Linked PRs

Activity

  1. changed the title [-]test_io failed with ASAN failures on AMD64 Arch Linux Asan 3.13[/-] [+]test_io failed with ASAN failures (heap-use-after-free) on AMD64 Arch Linux Asan 3.13[/+] on Jul 19, 2026
  2. BHUVANSH855 commented on Jul 25, 2026

    @BHUVANSH855
    Contributor

    I investigated this on the 3.13 branch.

    So far I've found that:

    • Both test_daemon_threads_shutdown_stdout_deadlock and test_daemon_threads_shutdown_stderr_deadlock pass locally.
    • Repeated execution (-F) also passes consistently on my release build.
    • I couldn't reproduce the reported heap-use-after-free outside of the ASAN buildbot.
    • I also didn't find any recent changes in Lib/test/test_io.py or Modules/_io that appear related.

    Since the buildbot log only contains the beginning of the AddressSanitizer report, I'm currently missing the stack trace showing where the use-after-free originates.

    Would it make sense to investigate this further only with an ASAN build, or is there another area of the runtime that is already suspected?

  3. cmaloney commented on Aug 29, 2026

    @cmaloney
    Contributor

    Have two potential improvements here:

    1. The ASAN failure is because _Py_eval_breaker_bit_is_set accesses tstate and, in 3.13, a finalizing main thread may free the tstate resulting in the use after free. For main this was fixed in race condition in threading when interpreter finalized while daemon thread runs (thread sanitizer identified) #124878 and suppressed in TSAN for 3.13. We could add an ASAN suppression to parallel the TSAN one but my leaning is just moving under the GIL a couple lines earlier.
      _Py_eval_breaker_bit_is_set(tstate, _PY_GIL_DROP_REQUEST_BIT)) {
    2. The test relies on time.sleep(0.5) to get the I/O stack blocked in a particular way which isn't great. There are tests in test_threading to make sure that an interpreter with daemon threads shuts down okay so I'd like to change this test_io to use a mocked Raw I/O which can use threading.Event to trigger the locking contention explicitly. That applies from main down to 3.13.
  4. encukou commented on Sep 9, 2026

    @encukou
    Member

    We could add an ASAN suppression to parallel the TSAN one but my leaning is just moving under the GIL a couple lines earlier.

    Well, since the HangThread changes weren't backported, daemon threads in 3.13 feel like a lost cause. If we handle the dangling tstate that in drop_gil, won't that just move the use-after-free to the next take_gil?

  5. cmaloney commented on Sep 14, 2026

    @cmaloney
    Contributor

    I think the drop_gil_impl call is what enables the tstate go from "definitely allocated" to "maybe allocated" and why we hit the ASAN failure. There are cases where tstate could be passed as NULL but I think the failure if we were hitting those would be a bit different.

    Daemon threads are used by quite a few projects... we can definitely just silence this particular test but not sure how that will be for SRE type work in deployments.

  6. added a commit that references this issue on Sep 29, 2026
  7. added a commit that references this issue on Oct 23, 2026
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

    testsTests in the Lib/test dirtopic-IOtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions