I'm seeing a difficult-to-reproduce crash in my application's test suite when creating/destroying windows with a toolbar in rapid succession.
This may or may not be related to a similar crash I reported last year (#24560). It has been happening with near 100% reliability when the tests are running on a GitHub Actions runner since an update(?) within the past month or so, it happens maybe 10-20% of the time on a fully up-to-date M1 Mac mini.
2025-08-25 19:22:14.143976+0100 all-tests[16679:4300190] [general] *** Assertion failure in -[wxNSToolbar _insertNewItemWithItemIdentifier:atIndex:propertyListRepresentation:notifyFlags:], NSToolbar.m:1621
Process 16679 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00000001864bfb7c libc++abi.dylib`__cxa_throw
libc++abi.dylib`__cxa_throw:
-> 0x1864bfb7c <+0>: pacibsp
0x1864bfb80 <+4>: stp x22, x21, [sp, #-0x30]!
0x1864bfb84 <+8>: stp x20, x19, [sp, #0x10]
0x1864bfb88 <+12>: stp x29, x30, [sp, #0x20]
Target 0: (all-tests) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x00000001864bfb7c libc++abi.dylib`__cxa_throw
frame #1: 0x0000000186126cf8 libobjc.A.dylib`objc_exception_throw + 448
frame #2: 0x0000000187c73a78 Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 288
frame #3: 0x000000018a5cbdac AppKit`-[NSToolbar _insertNewItemWithItemIdentifier:atIndex:propertyListRepresentation:notifyFlags:] + 236
frame #4: 0x000000018afc7428 AppKit`__51-[NSToolbar _notifyFamily_InsertedNewItem:atIndex:]_block_invoke + 196
frame #5: 0x000000018afc7058 AppKit`_enumerateToolbarsInFamily + 260
frame #6: 0x000000018a5cc654 AppKit`-[NSToolbar _insertItem:atIndex:notifyDelegate:notifyView:notifyFamilyAndUpdateDefaults:] + 736
frame #7: 0x000000018a5cbe38 AppKit`-[NSToolbar _insertNewItemWithItemIdentifier:atIndex:propertyListRepresentation:notifyFlags:] + 376
frame #8: 0x0000000100e6f7a4 all-tests`wxToolBar::Realize() + 644
frame #9: 0x0000000100177d60 all-tests`REHex::DiffWindow::DiffWindow(this=0x000000014207c600, parent=0x0000000142092a10) at DiffWindow.cpp:125:11
frame #10: 0x00000001001787b4 all-tests`REHex::DiffWindow::DiffWindow(this=0x000000014207c600, parent=0x0000000142092a10) at DiffWindow.cpp:103:1
frame #11: 0x0000000100898158 all-tests`DiffWindowTest::DiffWindowTest(this=0x0000000142092a00) at DiffWindow.cpp:78:22
frame #12: 0x0000000100898570 all-tests`DiffWindowTest_InsertDataAtEndOfRange_Test::DiffWindowTest_InsertDataAtEndOfRange_Test(this=0x0000000142092a00) at DiffWindow.cpp:111:1
frame #13: 0x0000000100898544 all-tests`DiffWindowTest_InsertDataAtEndOfRange_Test::DiffWindowTest_InsertDataAtEndOfRange_Test(this=0x0000000142092a00) at DiffWindow.cpp:111:1
frame #14: 0x00000001008984c4 all-tests`testing::internal::TestFactoryImpl<DiffWindowTest_InsertDataAtEndOfRange_Test>::CreateTest(this=0x00006000016a1b00) at gtest-internal.h:472:43
frame #15: 0x0000000100041748 all-tests`testing::Test* testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::TestFactoryBase, testing::Test*>(object=0x00006000016a1b00, method=0x00000000000000010000000000000010, location="the test fixture's constructor") at gtest.cc:2443:10
frame #16: 0x000000010000f088 all-tests`testing::Test* testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::TestFactoryBase, testing::Test*>(object=0x00006000016a1b00, method=0x00000000000000010000000000000010, location="the test fixture's constructor") at gtest.cc:2479:14
frame #17: 0x000000010000ef38 all-tests`testing::TestInfo::Run(this=0x0000000141722cc0) at gtest.cc:2684:22
frame #18: 0x000000010000fd28 all-tests`testing::TestCase::Run(this=0x0000000141722aa0) at gtest.cc:2811:28
frame #19: 0x000000010001a290 all-tests`testing::internal::UnitTestImpl::RunAllTests(this=0x0000000141705bc0) at gtest.cc:5177:43
frame #20: 0x000000010004628c all-tests`bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(object=0x0000000141705bc0, method=(all-tests`testing::internal::UnitTestImpl::RunAllTests() at gtest.cc:5084), location="auxiliary test code (environments or event listeners)") at gtest.cc:2443:10
frame #21: 0x0000000100019da8 all-tests`bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(object=0x0000000141705bc0, method=(all-tests`testing::internal::UnitTestImpl::RunAllTests() at gtest.cc:5084), location="auxiliary test code (environments or event listeners)") at gtest.cc:2479:14
frame #22: 0x0000000100019ca0 all-tests`testing::UnitTest::Run(this=0x0000000101faa1a8) at gtest.cc:4786:10
frame #23: 0x00000001009f38a4 all-tests`RUN_ALL_TESTS() at gtest.h:2341:46
frame #24: 0x00000001009f3504 all-tests`main(argc=1, argv=0x000000016fdff098) at main.cpp:87:9
frame #25: 0x0000000186166b98 dyld`start + 6076
I'm also not sure if this is related, but when running in lldb, warnings like the following are emitted, but not until after the above assertion failure (Google Test swallows it and allows the process to continue):
2025-08-25 22:01:25.723408+0100 all-tests[16679:4300190] [Window] WARNING: NSWindow has detected an excessive live window count of 101. Window <wxNSPanel: 0x111cd4730> windowNumber=2ce2 created after passing the threshold of 100. This window is not necessarily the cause, and this warning will only be shown once per window class. (
0 AppKit 0x000000018a528a50 -[NSWindow _setWindowNumber:] + 776
1 AppKit 0x000000018b0b2640 _NXCreateWindow + 552
2 AppKit 0x000000018a603b68 -[NSWindow _commonAwake] + 672
3 AppKit 0x000000018a527b74 -[NSWindow _commonInitFrame:styleMask:backing:defer:] + 1024
4 AppKit 0x000000018a527414 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 848
5 AppKit 0x000000018a67975c -[NSPanel _initContent:styleMask:backing:defer:contentView:] + 48
6 AppKit 0x000000018a5270b8 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 48
7 AppKit 0x000000018a679710 -[NSPanel initWithContentRect:styleMask:backing:defer:] + 48
8 all-tests 0x0000000100e64620 _ZN25wxNonOwnedWindowCocoaImpl6CreateEP8wxWindowRK7wxPointRK6wxSizellRK8wxString + 416
9 all-tests 0x0000000100e657f4 _ZN20wxNonOwnedWindowImpl20CreateNonOwnedWindowEP16wxNonOwnedWindowP8wxWindowRK7wxPointRK6wxSizellRK8wxString + 104
10 all-tests 0x0000000100dce48c _ZN16wxNonOwnedWindow6CreateEP8wxWindowiRK7wxPointRK6wxSizelRK8wxString + 332
11 all-tests 0x0000000100dd23c4 _ZN19wxTopLevelWindowMac6CreateEP8wxWindowiRK8wxStringRK7wxPointRK6wxSizelS4_ + 48
12 all-tests 0x0000000100d48078 _ZN12wxAuiManager22UpdateHintWindowConfigEv + 532
13 all-tests 0x0000000100d47768 _ZN12wxAuiManager16SetManagedWindowEP8wxWindow + 784
14 all-tests 0x0000000100d6558c _ZN13wxAuiNotebook12InitNotebookEl + 460
15 all-tests 0x0000000100d65380 _ZN13wxAuiNotebook6CreateEP8wxWindowiRK7wxPointRK6wxSizel + 140
16 all-tests 0x000000010016fc54 _ZN13wxAuiNotebookC2EP8wxWindowiRK7wxPointRK6wxSizel + 212
17 all-tests 0x00000001001710e4 _ZN13wxAuiNotebookC1EP8wxWindowiRK7wxPointRK6wxSizel + 68
18 all-tests 0x000000010017ae00 _ZN5REHex10DiffWindow9add_rangeERKNS0_5RangeE + 980
19 all-tests 0x00000001008954bc _ZN60DiffWindowTest_OverwriteDataOverlappingStartOfSelection_Test8TestBodyEv + 92
20 all-tests 0x00000001000414bc _ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc + 140
21 all-tests 0x000000010000dfa0 _ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc + 96
22 all-tests 0x000000010000def0 _ZN7testing4Test3RunEv + 180
23 all-tests 0x000000010000ef50 _ZN7testing8TestInfo3RunEv + 204
24 all-tests 0x000000010000fd28 _ZN7testing8TestCase3RunEv + 240
25 all-tests 0x000000010001a290 _ZN7testing8internal12UnitTestImpl11RunAllTestsEv + 712
26 all-tests 0x000000010004628c _ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc + 140
27 all-tests 0x0000000100019da8 _ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc + 96
28 all-tests 0x0000000100019ca0 _ZN7testing8UnitTest3RunEv + 208
29 all-tests 0x00000001009f38a4 _Z13RUN_ALL_TESTSv + 16
30 all-tests 0x00000001009f3504 main + 852
31 dyld 0x0000000186166b98 start + 6076
)
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
Sorry, no idea what causes the crash, but it looks like the tests might be leaking windows, i.e. is it really normal to have 100+ of them?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
It creates and destroys some top-level windows (wxFrame
) in rapid succession, but less than 100 in total, I assume it is counting child windows/controls too, and there's some kind of garbage collection which isn't getting a chance to run between tests.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
AFAIU some stuff is not getting destroyed until the auto release poll is emptied, so maybe you need to do this between iterations.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
I tried adding a call to wxGetApp().MacReleaseAutoreleasePool()
between tests, doesn't do anything about the too many windows warning.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
This may be a bug in my code - the tests are allocating a wxFrame
on the stack as the parent for the window being tested. Please close this as invalid if a stack-allocated wxFrame
is UB (which I suspect it is).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
@solemnwarning ,
It definitely is - all wxFrame classes are heap based. Look at any sample provided.
Thank you.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
@oneeyeman1 thanks, I wasn't sure if wxFrame
was one of the few window classes that were safe to delete directly (like wxDialog
) and couldn't find a definitive answer in the docs.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
Closed #25725 as not planned.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.
@solemnwarning ,
If you create TLW on stack it will be very short lived.
And if you cant find smth in the docs - look at the samples. They are the second best thing with wx. 😀
Thank you.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.