FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[Bug]: macosx backend, plots not closing, segfault · Issue #32019 · matplotlib/matplotlib · GitHub

Repository navigation

[Bug]: macosx backend, plots not closing, segfault #32019

Closed

Description

Bug summary

I am trying to create a plot in a for-loop. I can move each plot around, but even if I close it (click the ❌, use plt.close()), all prior plots are still displayed behind the newest plot. If I try to close plots (click the ❌) out of order, it results in a segfault.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

for _ in range(100):
    fig, ax = plt.subplots()
    x = np.random.rand(10)
    y = np.random.rand(10)
    ax.plot(x, y)
    plt.show()
    plt.close()

Actual outcome

> python3 -X faulthandler test.py
Fatal Python error: Segmentation fault

Current thread 0x00000001f5cc1e80 (most recent call first):
  File "/Users/Adam/torchgeo/.venv/lib/python3.14/site-packages/matplotlib/backends/backend_macosx.py", line 180 in start_main_loop
  File "/Users/Adam/torchgeo/.venv/lib/python3.14/site-packages/matplotlib/backend_bases.py", line 3702 in show
  File "/Users/Adam/torchgeo/.venv/lib/python3.14/site-packages/matplotlib/pyplot.py", line 646 in show
  File "/Users/Adam/Downloads/test.py", line 9 in <module>

Current thread's C stack trace (most recent call first):
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at _Py_DumpStack+0x44 [0x101cf10a4]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at faulthandler_dump_c_stack+0x54 [0x101d68f48]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at faulthandler_fatal_error+0x16c [0x101d68df8]
  Binary file "/usr/lib/system/libsystem_platform.dylib", at _sigtramp+0x38 [0x189b4b744]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at _Py_Dealloc+0x38 [0x1013b0238]
  Binary file "/Users/Adam/torchgeo/.venv/lib/python3.14/site-packages/matplotlib/backends/_macosx.cpython-314-darwin.so", at -[Window close]+0x7c [0x106c59f70]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSWindow __close]+0x178 [0x18e2e2ad8]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSApplication(NSResponder) sendAction:to:from:]+0x230 [0x18e1c66c0]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSControl sendAction:to:]+0x48 [0x18e1c6460]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at __26-[NSCell _sendActionFrom:]_block_invoke+0x64 [0x18e1c63a4]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSCell _sendActionFrom:]+0xcc [0x18e1c62cc]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSButtonCell _sendActionFrom:]+0x60 [0x18e1c61c8]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at NSControlTrackMouse+0x5d4 [0x18e1c37b0]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSCell trackMouse:inRect:ofView:untilMouseUp:]+0x90 [0x18e1c31b0]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:]+0xe4 [0x18e1c307c]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSControl(_NSTracking) _mouseDown:]+0x260 [0x18e712a74]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSControl(_NSTracking) mouseDown:]+0x68 [0x18e7127e8]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:]+0xe70 [0x18e1c1c04]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:]+0x1ec [0x18e1501f4]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSWindow(NSEventRouting) sendEvent:]+0x17c [0x18e14fe64]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSApplication(NSEventRouting) sendEvent:]+0x4fc [0x18ebc040c]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSApplication _handleEvent:]+0x3c [0x18e80d664]
  Binary file "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit", at -[NSApplication run]+0x198 [0x18e01f164]
  Binary file "/Users/Adam/torchgeo/.venv/lib/python3.14/site-packages/matplotlib/backends/_macosx.cpython-314-darwin.so", at show+0x74 [0x106c5e970]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at _TAIL_CALL_CALL_NON_PY_GENERAL.llvm.10127954890374434623+0x104 [0x101705924]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at _PyFunction_Vectorcall+0x338 [0x10167429c]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at method_vectorcall.llvm.1628862021063799139+0x94 [0x1016b7330]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at _TAIL_CALL_CALL_FUNCTION_EX.llvm.10127954890374434623+0x10c [0x101469578]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at _PyEval_Vector+0x30c [0x1014f5d00]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at PyEval_EvalCode+0xa0 [0x10150588c]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at run_mod.llvm.9148091775861049191+0x124 [0x101517a7c]
  Binary file "/Users/Adam/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/libpython3.14.dylib", at pyrun_file+0xa4 [0x101645880]
  <truncated rest of calls>

Extension modules: numpy._core._multiarray_umath, numpy.linalg._umath_linalg, PIL._imaging, kiwisolver._cext, matplotlib.backends._macosx, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._pcg64, numpy.random._generator, numpy.random._mt19937, numpy.random._philox, numpy.random._sfc64, numpy.random.mtrand (total: 14)
fish: Job 1, 'python3 -X faulthandler test.py' terminated by signal SIGSEGV (Address boundary error)

Expected outcome

I would expect no phantom plots and no segfaults.

Additional information

Tried Python 3.13 and 3.14 in fresh uv environments, no luck so far. Happy to try other debugging suggestions.

Operating system

macOS Tahoe 26.5.1

Matplotlib Version

3.11.0

Matplotlib Backend

macosx

Python version

3.14.4

Jupyter version

N/A

Installation

uv

Activity

  1. QuLogic commented on Jul 8, 2026

    Member

    This looks like #31106, but it should have been fixed in 3.11.0. @iccir

  2. iccir commented on Jul 9, 2026

    Contributor

    @adamjstewart If you open Console and click on "Crash Reports", can you attach the full crash report file?

  3. iccir commented on Jul 9, 2026

    Contributor

    The crash is caused by the Py_DECREF(manager) in -[Window close]. In the event that a window doesn't actually close and -[Window close] is called multiple times, we will over-release the manager and crash. This part is fixed by PR #31855.

    The remaining question is "why is the window not closing." The only way that the over-release could happen is if -[Window close], and thus -[NSWindow close], was called at least once. That should have closed the window. The fact that it didn't is either a rare system bug of some kind, or (possibly) there's some kind of binary getting loaded into the Python process that changes the behavior of -[NSWindow close].

    I haven't been able to reproduce on Tahoe 26.5. I'm not able to update to 26.5.1 since it's no longer available, but I'm installing 26.5.2 now.

    Edit: I cannot reproduce on 26.5.2.

  4. adamjstewart commented on Jul 9, 2026

    ContributorAuthor

    I believe my problem is a bit different than #31106, recorded a video to demonstrate:

    Screen.Recording.2026-07-09.at.12.20.55.PM.mov

    Here is the crash report:

    proactive_event_tracker-com_apple_Trial-com_apple_triald_system_2026-07-08-203342_Vesuvius.txt

  5. iccir commented on Jul 9, 2026

    Contributor

    @adamjstewart - I need the IPS file for the crashed Python process. It should look like the attached screenshot (P.S. Nice computer name!)

  6. iccir commented on Jul 9, 2026

    Contributor

    @adamjstewart - Or you can copy-paste the whole contents of the crash dialog that pops up. Specifically, I need to see the Binary Images: section. That said, it looks like you have System Integrity Protection enabled, so it's doubtful there is something injecting into the Python process, but I want to be 100% sure.

  7. adamjstewart commented on Jul 9, 2026

    ContributorAuthor

    Full report:

    python3.14-2026-07-09-122132.txt

    Binary Images section:

    Binary Images:
           0x10099c000 -        0x10099ffff python3.14 (*) <4c4c44d0-5555-3144-a1cf-0eed2798e3b6> /Users/USER/*/python3.14
           0x101ef4000 -        0x102cb7fff libpython3.14.dylib (*) <4c4c4411-5555-3144-a17a-7cafb32817ed> /Users/USER/*/libpython3.14.dylib
           0x1019f8000 -        0x101d27fff _multiarray_umath.cpython-314-darwin.so (*) <b7bec910-4300-3b08-87c2-7410b4042f7b> /Users/USER/*/_multiarray_umath.cpython-314-darwin.so
           0x10110c000 -        0x101123fff _umath_linalg.cpython-314-darwin.so (*) <744167ce-fc38-3b32-b07d-18c58c5eef47> /Users/USER/*/_umath_linalg.cpython-314-darwin.so
           0x101924000 -        0x10193ffff _c_internal_utils.cpython-314-darwin.so (*) <4e4f2b8b-d5db-3710-a1ac-165ef08b756a> /Users/USER/*/_c_internal_utils.cpython-314-darwin.so
           0x1075b0000 -        0x10761bfff _imaging.cpython-314-darwin.so (*) <fa291eec-3799-3e32-b188-59c5109c45e0> /Users/USER/*/_imaging.cpython-314-darwin.so
           0x107704000 -        0x1077a3fff libtiff.6.dylib (*) <d6423d17-c1d0-3d07-878a-9313993f323b> /Users/USER/*/libtiff.6.dylib
           0x107648000 -        0x1076d3fff libjpeg.62.4.0.dylib (*) <ed74d7ae-7c43-3421-9076-3139840106a9> /Users/USER/*/libjpeg.62.4.0.dylib
           0x1077c0000 -        0x10784bfff libopenjp2.2.5.4.dylib (*) <1ccae3df-8f33-3d89-a003-74ab46296cce> /Users/USER/*/libopenjp2.2.5.4.dylib
           0x101954000 -        0x10196ffff libz.1.3.1.zlib-ng.dylib (*) <9ea7c0dd-e134-3f03-993d-5684959b80ca> /Users/USER/*/libz.1.3.1.zlib-ng.dylib
           0x101980000 -        0x1019a7fff libxcb.1.1.0.dylib (*) <e113eb59-2487-3314-ba50-a1600863d73d> /Users/USER/*/libxcb.1.1.0.dylib
           0x1078b4000 -        0x1078effff liblzma.5.dylib (*) <44f9e356-56ff-3bbf-a891-ac38f38d5bcf> /Users/USER/*/liblzma.5.dylib
           0x100d20000 -        0x100d23fff libXau.6.dylib (*) <076c8f8e-760a-39f4-a37c-3f99e4b3ed4c> /Users/USER/*/libXau.6.dylib
           0x107a60000 -        0x107a9bfff _path.cpython-314-darwin.so (*) <c87d5587-1af0-3954-8502-75847fd8b7a1> /Users/USER/*/_path.cpython-314-darwin.so
           0x108154000 -        0x108383fff ft2font.cpython-314-darwin.so (*) <c60a47ba-3741-3aef-8a42-5d16c8bfb9dd> /Users/USER/*/ft2font.cpython-314-darwin.so
           0x107a04000 -        0x107a1ffff _cext.cpython-314-darwin.so (*) <c44649de-1d19-3ca7-8cf3-a30048c14c0a> /Users/USER/*/_cext.cpython-314-darwin.so
           0x1083f0000 -        0x108437fff _image.cpython-314-darwin.so (*) <e6dfb21b-58ee-3ecc-af0e-62fb80327c71> /Users/USER/*/_image.cpython-314-darwin.so
           0x107864000 -        0x107873fff _macosx.cpython-314-darwin.so (*) <ee3bac7d-c64b-3a2d-9be4-655e9e0e2780> /Users/USER/*/_macosx.cpython-314-darwin.so
           0x108e54000 -        0x108eabfff _backend_agg.cpython-314-darwin.so (*) <c24d99b6-9149-37eb-8fcf-41041766a867> /Users/USER/*/_backend_agg.cpython-314-darwin.so
           0x108124000 -        0x10812ffff libobjc-trampolines.dylib (*) <ca58aa96-b997-3a6d-9132-19d49be4b3e9> /usr/lib/libobjc-trampolines.dylib
           0x10dddc000 -        0x10de17fff _bounded_integers.cpython-314-darwin.so (*) <8b30334f-11da-3f8b-acfb-6f712c47f883> /Users/USER/*/_bounded_integers.cpython-314-darwin.so
           0x10de28000 -        0x10de4bfff bit_generator.cpython-314-darwin.so (*) <efff086a-20b8-3371-8717-fd9dc880119c> /Users/USER/*/bit_generator.cpython-314-darwin.so
           0x10de5c000 -        0x10de87fff _common.cpython-314-darwin.so (*) <60fad40d-df63-3757-80f8-dd979eef201a> /Users/USER/*/_common.cpython-314-darwin.so
           0x10df38000 -        0x10dfc3fff _generator.cpython-314-darwin.so (*) <98e0a692-f57b-3135-a48d-88a95a40f42c> /Users/USER/*/_generator.cpython-314-darwin.so
           0x10ddb4000 -        0x10ddc7fff _pcg64.cpython-314-darwin.so (*) <def24177-64ad-3b37-8507-f7bb8fe7654f> /Users/USER/*/_pcg64.cpython-314-darwin.so
           0x10de98000 -        0x10deabfff _mt19937.cpython-314-darwin.so (*) <b027d328-783d-3293-a5cc-bd97449c5354> /Users/USER/*/_mt19937.cpython-314-darwin.so
           0x10debc000 -        0x10decbfff _philox.cpython-314-darwin.so (*) <8e53fd25-688b-3642-8e9c-8de943702c9e> /Users/USER/*/_philox.cpython-314-darwin.so
           0x10dedc000 -        0x10dee7fff _sfc64.cpython-314-darwin.so (*) <c5ea334e-c1ae-3d70-909e-1e90c02859d4> /Users/USER/*/_sfc64.cpython-314-darwin.so
           0x10e064000 -        0x10e0d7fff mtrand.cpython-314-darwin.so (*) <9a9dfeb3-9dac-3ea7-b3b9-36f36bbfc8ad> /Users/USER/*/mtrand.cpython-314-darwin.so
           0x10f774000 -        0x10ff77fff com.apple.AGXMetalG14X (351.2) <c71ae01d-a535-38c0-84c6-7e23cc4cda3e> /System/Library/Extensions/AGXMetalG14X.bundle/Contents/MacOS/AGXMetalG14X
           0x189afd000 -        0x189b3a2af libsystem_kernel.dylib (*) <cc1cf985-bc65-3725-809f-4c1e36b8f4ba> /usr/lib/system/libsystem_kernel.dylib
           0x189b3b000 -        0x189b47b3b libsystem_pthread.dylib (*) <4f33683c-18c8-39a1-800b-2e3bd43bcc13> /usr/lib/system/libsystem_pthread.dylib
           0x1899d0000 -        0x189a50d9f libsystem_c.dylib (*) <694b7881-1bf3-3d0f-8f19-b50ae4e8ef8a> /usr/lib/system/libsystem_c.dylib
           0x189b48000 -        0x189b50963 libsystem_platform.dylib (*) <160fd864-8d15-36fc-9e97-9725388cfafe> /usr/lib/system/libsystem_platform.dylib
           0x18dff3000 -        0x18f715f9f com.apple.AppKit (6.9) <cf57a4fc-4be3-3d95-b543-d744e8718b26> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
           0x189764000 -        0x18980a217 dyld (*) <a237ef81-b68b-37ba-a165-92c965529534> /usr/lib/dyld
                   0x0 - 0xffffffffffffffff ??? (*) <00000000-0000-0000-0000-000000000000> ???
           0x189b81000 -        0x18a0df31f com.apple.CoreFoundation (6.9) <04e3598b-f226-3250-b3b2-ce938dd4db7e> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
    
  8. iccir commented on Jul 9, 2026

    Contributor

    @adamjstewart - Thank you! I don't see anything in that Binary Image list that could be affecting window closing.

    Can you do the following:

    1. In a separate Terminal window, run the following command:
    log stream --predicate 'subsystem == "com.apple.AppKit" AND category == "Window" AND process CONTAINS "python" AND NOT message CONTAINS "esize"' --level debug --style compact
    
    1. Take another screen recording showing the issue while that command's output is visible.
  9. adamjstewart commented on Jul 9, 2026

    ContributorAuthor

    Log:

    > log stream --predicate 'subsystem == "com.apple.AppKit" AND category == "Window" AND process CONTAINS "python" AND NOT message CONTAINS "esize"' --level debug --style compact
    Filtering the log data using "subsystem == "com.apple.AppKit" AND category == "Window" AND process CONTAINS "python" AND (NOT composedMessage CONTAINS "esize")"
    Timestamp               Ty Process[PID:TID]
    2026-07-09 14:38:37.648 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window Window 0x7121dc280 context 0 -> 6e45aa92
    2026-07-09 14:38:37.648 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> 6e45aa92) for window 27ad
    2026-07-09 14:38:37.650 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] Window <Window: 0x7121dc280> windowNumber=27ad ordered front from a non-active application and may order beneath the active application's windows.
    2026-07-09 14:38:37.650 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27ad related: 0
    2026-07-09 14:38:37.653 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window: 27ad op: 1 relative: 0 related: 0
    2026-07-09 14:38:37.655 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] Window <Window: 0x7121dc280> windowNumber=27ad ordered front from a non-active application and may order beneath the active application's windows.
    2026-07-09 14:38:37.655 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27ad related: 0
    2026-07-09 14:38:37.678 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window NSMenuBarReplicantWindow 0x71235c000 context 0 -> 4af4ac66
    2026-07-09 14:38:37.678 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> 4af4ac66) for window 27b1
    2026-07-09 14:38:37.678 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window NSMenuBarReplicantWindow 0x7122cf980 context 0 -> 4671bb1a
    2026-07-09 14:38:37.678 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> 4671bb1a) for window 27b0
    2026-07-09 14:38:37.678 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window NSMenuBarReplicantWindow 0x7122cf480 context 0 -> 2a59b374
    2026-07-09 14:38:37.678 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> 2a59b374) for window 27af
    2026-07-09 14:38:37.678 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window NSMenuBarReplicantWindow 0x7122cef80 context 0 -> b95509af
    2026-07-09 14:38:37.678 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> b95509af) for window 27ae
    2026-07-09 14:38:37.726 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27ad related: 0
    2026-07-09 14:38:46.628 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] window <Window: 0x7121dc280> windowNumber=27ad finishing close
    2026-07-09 14:38:46.645 Df python3.14[35094:1affb2] [com.apple.AppKit:Window] window <Window: 0x7121dc280> windowNumber=27ad windowShouldClose: prevented close
    2026-07-09 14:38:46.664 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window Window 0x71235f480 context 0 -> d88c3839
    2026-07-09 14:38:46.664 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> d88c3839) for window 27b4
    2026-07-09 14:38:46.664 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] Window <Window: 0x71235f480> windowNumber=27b4 ordered front from a non-active application and may order beneath the active application's windows.
    2026-07-09 14:38:46.664 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27b4 related: 0
    2026-07-09 14:38:46.665 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window: 27b4 op: 1 relative: 0 related: 0
    2026-07-09 14:38:46.668 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] Window <Window: 0x7121dc280> windowNumber=27ad ordered front from a non-active application and may order beneath the active application's windows.
    2026-07-09 14:38:46.668 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27ad related: 0
    2026-07-09 14:38:46.670 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] Window <Window: 0x71235f480> windowNumber=27b4 ordered front from a non-active application and may order beneath the active application's windows.
    2026-07-09 14:38:46.670 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27b4 related: 0
    2026-07-09 14:38:46.707 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27b4 related: 0
    2026-07-09 14:38:51.629 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] window <Window: 0x7121dc280> windowNumber=27ad finishing close
    2026-07-09 14:38:51.631 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] window <Window: 0x71235f480> windowNumber=27b4 finishing close
    2026-07-09 14:38:51.660 Db python3.14[35094:1affb2] [com.apple.AppKit:Window] Window Window 0x711cb5b80 context 0 -> 245bfba0
    2026-07-09 14:38:51.660 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] context (0 -> 245bfba0) for window 27b6
    2026-07-09 14:38:51.663 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27b6 related: 0
    2026-07-09 14:38:51.663 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window: 27b6 op: 1 relative: 0 related: 0
    2026-07-09 14:38:51.665 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27ad related: 0
    2026-07-09 14:38:51.665 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27b4 related: 0
    2026-07-09 14:38:51.668 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] order window front conditionally: 27b6 related: 0
    2026-07-09 14:38:55.850 I  python3.14[35094:1affb2] [com.apple.AppKit:Window] window <Window: 0x7121dc280> windowNumber=27ad finishing close
    

    Screen recording:

    Screen.Recording.2026-07-09.at.2.38.32.PM.mov
  10. iccir commented on Jul 9, 2026

    Contributor

    Thanks!

    Here's what is happening: for some unknown reason, something in the process is maintaining a strong reference to each NSWindow instance. Per the logs, the NSWindow's delegate is getting set to nil; hence, either FigureManager_destroy or FigureManager_dealloc is being called. The code in question:

    [self->window close];
    [self->window setDelegate:nil];
    [self->window release];

    That -release should be the last strong reference to the window. One would expect -[NSWindow dealloc] to get called shortly after. However, that doesn't happen. Until -dealloc is called, the window will never be removed from the NSApplications.windows array.

    The next time show() is called, we iterate over all known windows and show them:

    NSArray *windowsArray = [NSApp windows];
    NSEnumerator *enumerator = [windowsArray objectEnumerator];
    NSWindow *window;
    while ((window = [enumerator nextObject])) {
        [window orderFront:nil];
    }

    So that causes the window to re-appear. However, without #31855, that window contains an uncleared backpointer to the FigureManager, so it's going to explode if the manager goes away.

    show() should probably iterate over Window classes (those that are owned by a FigureManager) instead of all living windows.

    While #31855 fixes the crash, it likely doesn't fix the fact that something outside of our control is maintaining a strong reference to the window. I don't know if that's fixable or not. It's likely that strong reference would eventually go away in another run loop cycle or two, it's just that we immediately spin down the event loop and then spin it back up on the next call to show().


    @adamjstewart - Can you do the following:

    Use the command heap -q --addresses=Window python3 | grep Window. This will tell you how many active Windows are still allocated in the process.

    If you run your original Python script, you should see window objects accumulate with each iteration.

    Try to run the following (slightly scary-looking) script:

    import numpy as np
    import matplotlib.pyplot as plt
    import signal
    
    def on_close(event):
        canvas = event.canvas
        signal.signal(signal.SIGALRM, lambda signum, frame: canvas.stop_event_loop())
        signal.setitimer(signal.ITIMER_REAL, 0.001)
    
    for _ in range(100):
        fig, ax = plt.subplots()
        x = np.random.rand(10)
        y = np.random.rand(10)
        ax.plot(x, y)
        fig.canvas.mpl_connect('close_event', on_close)
        fig.show()
        fig.canvas.start_event_loop()

    Let me know if you see the Window objects continue to accumulate or go away. Maybe change that 0.001 to a higher value too if they are still accumulating.

  11. adamjstewart commented on Jul 9, 2026

    ContributorAuthor

    If you run your original Python script, you should see window objects accumulate with each iteration.

    Can confirm this behavior.

    Try to run the following (slightly scary-looking) script

    First plot displays, I can close it without it coming back, but the second plot never displays. Possibly stuck in a loop somewhere? I can also try a time.sleep() or del fig if that makes sense.

  12. iccir commented on Jul 9, 2026

    Contributor

    First plot displays, I can close it without it coming back, but the second plot never displays. Possibly stuck in a loop somewhere? I can also try a time.sleep() or del fig if that makes sense.

    Yeah, I'm seeing that now too. That's what I get for trying to be clever and working around another bug ;)

    Can you try this:

    import numpy as np
    import matplotlib.pyplot as plt
    import signal
    
    for _ in range(100):
        fig, ax = plt.subplots()
        x = np.random.rand(10)
        y = np.random.rand(10)
        ax.plot(x, y)
        fig.show()
        fig.canvas.start_event_loop(2)

    And then quickly hit the close button as the windows appear? We are hoping to see previously-closed windows not re-appear and for the heap command to not show the previously-closed ones.

  13. adamjstewart commented on Jul 9, 2026

    ContributorAuthor

    This works, although it spawns a new figure every 2 sec instead of waiting for me to close the old one.

  14. iccir commented on Jul 9, 2026

    Contributor

    This works, although it spawns a new figure every 2 sec instead of waiting for me to close the old one.

    So, to confirm, as long as you are quick enough you can keep the window count down to 1?

    This is all great information, thank you for all the help thus far!

  15. adamjstewart commented on Jul 9, 2026

    ContributorAuthor

    Correct

  16. iccir commented on Jul 10, 2026

    Contributor

    @adamjstewart - I believe that the following workaround should work until I can get a proper fix landed. You may need to add a plt.close() after plt.show() or increase the start_event_loop timeout a bit.

    See note below: this isn't going to work as the AppKit seems to retain the last-animated window.

    import numpy as np
    import matplotlib.pyplot as plt
    
    for _ in range(100):
        fig, ax = plt.subplots()
        x = np.random.rand(10)
        y = np.random.rand(10)
        ax.plot(x, y)
        plt.show()
        plt.close()
        fig.canvas.start_event_loop(0.01)
  17. iccir commented on Jul 10, 2026

    Contributor

    Update: I can reproduce this 100% on Tahoe if I turn off Reduce Motion. The window is being retained by AppKit due to the order-out animation and AppKit seems to keep a strong reference to it until the next window is ordered in.

  18. iccir commented on Jul 10, 2026

    Contributor

    After some testing today, I can confirm that this is fixed by #31855. AppKit is still maintaining a reference to one of our Window objects, but that eventually clears when the next window is shown.

  19. QuLogic commented on Jul 16, 2026

    Member

    That's good; is there a more focused fix that we can backport or is that PR the best option?

  20. iccir commented on Jul 17, 2026

    Contributor

    That's good; is there a more focused fix that we can backport or is that PR the best option?

    I think that the PR is the best option. I could try to make a more-focused fix with just 80a4327 and parts of the FigureManager_dealloc/FigureManager_destroy changes; however, I'm uneasy about the amount of testing those fixes in isolation would received compared to the amount that the whole ARC PR has received.

  21. added this to the v3.12.0 milestone on Jul 24, 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

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL