Is this called by EnableMenuItems at all ?
No. To have the crash occur, the user does not touch the menu but instead takes another action which causes the two menus to get torn down and recreated. However, if before taking that action, the user clicks on the menu so it drops down and then clicks again to put it away, then the crash does not occur. Crash occurs (or not) on quitting the app after these actions.
I tried adding app.RefreshMenuBar() - replacement for app.EnableMenuItems() - at the end of the menu build process. It made no difference.
The menus are defined in the IDE but are left unpopulated. App initialisation populates them until some later user action (which changes what the menus need to contain) causes them to be torn down and rebuilt.
Errm, why might the ptr be Nil? The for loop will remove the number of menu items that are there, as I explained in my response too rich. Iāve never had a NilPointerException in that code.
Interesting, but it made no difference. Might be a bit faster but not apparent if so. All the menu items will either have a file or a directory image as the icon, except a couple that donāt, but the submenus always will which is why I coded it that way.
This is a good question. Iāve not tried just removing the items and not bothering to recurse; the Xojo documentation is silent on too many areas of detail and this is one of them. I suppose that ought to work - I could just try commenting out the recursion call. I never close a menu (is this necessary? If so, who knew? Not me, eh!), I just remove them.
Edit: commenting out the recursive descent call in the method that empties a menu, in fact appears to work in that the app works as expected. The crash still occurs, however (expected perhaps because this is a new install situation, when the menus that will get created at startup only have a few items and no submenus).
Yes, I understand how youāre removing the menu items. But because I canāt reproduce the crash, this was just I wild guess on my part. You never knowā¦
If I dynamically build menus, I always .Close
the items I donāt need anymore. The .Close
will also remove the menu item, so you then canāt also call .Remove
.
You do have to be careful with this though
That was the bug report I posted a while back
If an item is invoked (via a short cut OR user manipulation) and then removed in the EnableMenuItems event which occurs BEFORE the action for that menu item you crash
I did also file a recent bug report about using close in enable menu items
feedback://showreport?report_id=59284
Its absolutely reproducible
Did you ever post your crash log? Have you tried to disable the menus items instead of removing the items?
A quick and dirty workaround is to use Appleās Terminate function on cancel close. This causes the app to die instantly, rather than wind down everything first.
Some really old declares that will do it.
Declare Function NSClassFromString Lib āCocoa.frameworkā (className as CFStringRef) As Ptr
declare sub terminate lib āCocoa.frameworkā selector āterminate:ā ( appRef as Ptr, sender as Ptr )
declare function sharedApplication lib āCocoa.frameworkā selector āsharedApplicationā ( classRef as Ptr ) as Ptr
terminate sharedApplication( NSClassFromString( āNSApplicationā ) ), nil
You mean via feedback? Not yet as I wanted to make a bit more progress on my app, which Iāve now done. If I disable instead of removing menu items, presumably the old items stay visible, while unusable, and a near-identical new set gets added after them.
I do quite a lot in the windowās cancel close. Do you mean at the end of that particular cancel close, or some other one? Or might it go in application.close? Could be interesting to move it around and see where it prevents the crash, if at all.
No, I meant that you could post your crash log here. You can disable and enable the menu items instead of removing them and recreating the menu.
OK, Iāll post it here.
Re: the menus: the reason for removing/recreating them is that they wonāt necessarily be the same as they were.
Changing the interface is not a good idea. Enabling and disabling is nicer for the user.
The menu content is under the userās control. That is why it needs updating.
Hereās the first 8k chars or so of the crash. I canāt post more than 32k chars or upload a text file, it seems.
Process: iLetter.debug [9316]
Path: /Users/USER/*/iLetter.debug.app/Contents/MacOS/iLetter.debug
Identifier: com.personal.iletter
Version: v2.0 D3B155 (2.0.0.0.0)
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: iLetter.debug [9316]
User ID: 501
Date/Time: 2020-05-15 15:48:55.105 +0100
OS Version: Mac OS X 10.14.6 (18G4032)
Report Version: 12
Bridge OS Version: 4.4 (17P4263)
Anonymous UUID: C7515A30-E135-A886-3141-103FF53813AA
Time Awake Since Boot: 3800000 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [9316]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 XojoFramework 0x0000000104841c0b std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::__tree_node<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, void*>*, long>, std::__1::__tree_iterator<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::__tree_node<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, void*>*, long> > std::__1::__tree<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::__map_value_compare<RuntimeObject*, std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::less<RuntimeObject*>, true>, std::__1::allocator<std::__1::__value_type<RuntimeObject*, RuntimeObject**> > >::__equal_range_multi<RuntimeObject*>(RuntimeObject* const&) + 41
1 XojoFramework 0x0000000104840d75 RuntimeUnlockObject + 695
2 XojoFramework 0x0000000104699ab7 std::__1::__vector_base<RBObject<RunMenuItem*>, std::__1::allocator<RBObject<RunMenuItem*> > >::~__vector_base() + 49
3 libsystem_c.dylib 0x00007fff704693cf __cxa_finalize_ranges + 319
4 libsystem_c.dylib 0x00007fff704696b3 exit + 55
5 libdyld.dylib 0x00007fff703c33dc start + 8
Thread 1:
0 libsystem_pthread.dylib 0x00007fff705b63f0 start_wqthread + 0
Thread 2:
0 libsystem_pthread.dylib 0x00007fff705b63f0 start_wqthread + 0
Thread 3:
0 libsystem_pthread.dylib 0x00007fff705b63f0 start_wqthread + 0
Thread 4:: JavaScriptCore bmalloc scavenger
0 libsystem_kernel.dylib 0x00007fff704fb866 __psynch_cvwait + 10
1 libsystem_pthread.dylib 0x00007fff705ba56e _pthread_cond_wait + 722
2 libc++.1.dylib 0x00007fff6d5f4b31 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock<std::__1::mutex>&, std::__1::chrono::time_point<std::__1::chrono::system_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >) + 93
3 com.apple.JavaScriptCore 0x00007fff47946235 std::__1::cv_status std::__1::condition_variable::wait_until<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >(std::__1::unique_lock<std::__1::mutex>&, std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > > const&) + 117
4 com.apple.JavaScriptCore 0x00007fff479460ff std::__1::cv_status std::__1::condition_variable_any::wait_until<std::__1::unique_lock<bmalloc::Mutex>, std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >(std::__1::unique_lock<bmalloc::Mutex>&, std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > > const&) + 95
5 com.apple.JavaScriptCore 0x00007fff47944dc6 bmalloc::Scavenger::threadRunLoop() + 262
6 com.apple.JavaScriptCore 0x00007fff47944579 bmalloc::Scavenger::threadEntryPoint(bmalloc::Scavenger*) + 9
7 com.apple.JavaScriptCore 0x00007fff47945ee7 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(bmalloc::Scavenger*), bmalloc::Scavenger*> >(void*) + 39
8 libsystem_pthread.dylib 0x00007fff705b72eb _pthread_body + 126
9 libsystem_pthread.dylib 0x00007fff705ba249 _pthread_start + 66
10 libsystem_pthread.dylib 0x00007fff705b640d thread_start + 13
Thread 5:: com.apple.NSEventThread
0 libsystem_kernel.dylib 0x00007fff704f821a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff704f8768 mach_msg + 60
2 com.apple.CoreFoundation 0x00007fff4445f99e __CFRunLoopServiceMachPort + 328
3 com.apple.CoreFoundation 0x00007fff4445ef0c __CFRunLoopRun + 1612
4 com.apple.CoreFoundation 0x00007fff4445e66e CFRunLoopRunSpecific + 455
5 com.apple.AppKit 0x00007fff41a5c4a2 _NSEventThread + 175
6 libsystem_pthread.dylib 0x00007fff705b72eb _pthread_body + 126
7 libsystem_pthread.dylib 0x00007fff705ba249 _pthread_start + 66
8 libsystem_pthread.dylib 0x00007fff705b640d thread_start + 13
Thread 6:: com.apple.CFStream.LegacyThread
0 libsystem_kernel.dylib 0x00007fff704f821a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff704f8768 mach_msg + 60
2 com.apple.CoreFoundation 0x00007fff4445f99e __CFRunLoopServiceMachPort + 328
3 com.apple.CoreFoundation 0x00007fff4445ef0c __CFRunLoopRun + 1612
4 com.apple.CoreFoundation 0x00007fff4445e66e CFRunLoopRunSpecific + 455
5 com.apple.CoreFoundation 0x00007fff4450d52a _legacyStreamRunLoop_workThread + 251
6 libsystem_pthread.dylib 0x00007fff705b72eb _pthread_body + 126
7 libsystem_pthread.dylib 0x00007fff705ba249 _pthread_start + 66
8 libsystem_pthread.dylib 0x00007fff705b640d thread_start + 13
Thread 7:
0 libsystem_pthread.dylib 0x00007fff705b63f0 start_wqthread + 0
Thread 8:
0 libsystem_pthread.dylib 0x00007fff705b63f0 start_wqthread + 0
Thread 9:: com.apple.NSURLConnectionLoader
0 libsystem_kernel.dylib 0x00007fff704f821a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff704f8768 mach_msg + 60
2 com.apple.CoreFoundation 0x00007fff4445f99e __CFRunLoopServiceMachPort + 328
3 com.apple.CoreFoundation 0x00007fff4445ef0c __CFRunLoopRun + 1612
4 com.apple.CoreFoundation 0x00007fff4445e66e CFRunLoopRunSpecific + 455
5 com.apple.CFNetwork 0x00007fff43343014 -[__CoreSchedulingSetRunnable runForever] + 210
6 com.apple.Foundation 0x00007fff466ba0e2 __NSThread__start__ + 1194
7 libsystem_pthread.dylib 0x00007fff705b72eb _pthread_body + 126
8 libsystem_pthread.dylib 0x00007fff705ba249 _pthread_start + 66
9 libsystem_pthread.dylib 0x00007fff705b640d thread_start + 13
Thread 10:: com.apple.CFSocket.private
0 libsystem_kernel.dylib 0x00007fff704ff616 __select + 10
1 com.apple.CoreFoundation 0x00007fff4448d322 __CFSocketManager + 635
2 libsystem_pthread.dylib 0x00007fff705b72eb _pthread_body + 126
3 libsystem_pthread.dylib 0x00007fff705ba249 _pthread_start + 66
4 libsystem_pthread.dylib 0x00007fff705b640d thread_start + 13
Thread 0 crashed with X86 Thread State (64-bit):
rax: 0x00007f854f840ab8 rbx: 0x0000000000000000 rcx: 0x0000600002091370 rdx: 0x00008b3637884060
rdi: 0x0000600001cb4060 rsi: 0x00007ffeec6e1ac0 rbp: 0x00007ffeec6e1aa0 rsp: 0x00007ffeec6e1aa0
r8: 0x00000000033ff747 r9: 0xffffffff00000000 r10: 0x00007fffa6b590c8 r11: 0x0000000000000010
r12: 0x0000000000000002 r13: 0x00007ffeec6e1ac0 r14: 0x0000000104a04a30 r15: 0x0000600002091370
rip: 0x0000000104841c0b rfl: 0x0000000000010206 cr2: 0x000000010467505a
Logical CPU: 1
Error Code: 0x00000000
Trap Number: 13
Well thatās interesting. I put your code on a button (in a method named quitRightNow). I then did the crash-provoking steps, and clicked my button. Still crashed, but the traceback for Thread zero is here:
Process: iLetter.debug [9390]
Path: /Users/USER/*/iLetter.debug.app/Contents/MacOS/iLetter.debug
Identifier: com.personal.iletter
Version: v2.0 D3B155 (2.0.0.0.0)
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: iLetter.debug [9390]
User ID: 501
Date/Time: 2020-05-15 16:00:18.497 +0100
OS Version: Mac OS X 10.14.6 (18G4032)
Report Version: 12
Bridge OS Version: 4.4 (17P4263)
Anonymous UUID: C7515A30-E135-A886-3141-103FF53813AA
Time Awake Since Boot: 3800000 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [9390]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 XojoFramework 0x0000000110a94c0b std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::__tree_node<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, void*>*, long>, std::__1::__tree_iterator<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::__tree_node<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, void*>*, long> > std::__1::__tree<std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::__map_value_compare<RuntimeObject*, std::__1::__value_type<RuntimeObject*, RuntimeObject**>, std::__1::less<RuntimeObject*>, true>, std::__1::allocator<std::__1::__value_type<RuntimeObject*, RuntimeObject**> > >::__equal_range_multi<RuntimeObject*>(RuntimeObject* const&) + 41
1 XojoFramework 0x0000000110a93d75 RuntimeUnlockObject + 695
2 XojoFramework 0x00000001108ecab7 std::__1::__vector_base<RBObject<RunMenuItem*>, std::__1::allocator<RBObject<RunMenuItem*> > >::~__vector_base() + 49
3 libsystem_c.dylib 0x00007fff704693cf __cxa_finalize_ranges + 319
4 libsystem_c.dylib 0x00007fff704696b3 exit + 55
5 com.apple.AppKit 0x00007fff41c56b5d -[NSApplication terminate:] + 1760
6 iLetter.debug 0x000000010fdd17c7 Operation.quitRightNow + 407 (/Operation:2848)
7 iLetter.debug 0x000000010fec5ec8 ButtonsMailboxes.ButtonsMailboxes.BarButton2_MouseUp%%o<ButtonsMailboxes.ButtonsMailboxes>o<BarButton>i8i8 + 984 (/ButtonsMailboxes:1366)
8 iLetter.debug 0x000000010fecbee4 Delegate.IM_Invoke%%o<BarButton>i8i8 + 68
9 iLetter.debug 0x000000010fecbf5e AddHandler.Stub.23%%i8i8 + 94
10 XojoFramework 0x0000000110989e46 RuntimeCanvas::HandleMouseUp(xojo::Value<xojo::Points>, xojo::Value<xojo::Points>) + 106
11 XojoFramework 0x000000011091a00e 0x110826000 + 999438
12 XojoFramework 0x000000011091537b 0x110826000 + 979835
13 com.apple.AppKit 0x00007fff41bc001a -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 1899
14 com.apple.AppKit 0x00007fff41bbf667 -[NSWindow(NSEventRouting) sendEvent:] + 478
15 XojoFramework 0x00000001109163a1 0x110826000 + 983969
16 com.apple.AppKit 0x00007fff41a5ee4b -[NSApplication(NSEvent) sendEvent:] + 331
17 XojoFramework 0x0000000110905b7b 0x110826000 + 916347
18 iLetter.debug 0x000000010f9f9466 Delegate.Invoke%% + 22
19 iLetter.debug 0x000000010f8579c7 Application._CallFunctionWithExceptionHandling%%o<Application>p + 391
20 XojoFramework 0x0000000110a91645 CallFunctionWithExceptionHandling(void (*)()) + 262
21 XojoFramework 0x0000000110905af6 0x110826000 + 916214
22 com.apple.AppKit 0x00007fff41a4d5c0 -[NSApplication run] + 755
23 XojoFramework 0x0000000110a8fa51 RuntimeRun + 42
24 iLetter.debug 0x000000010f9aed75 REALbasic._RuntimeRun + 37
25 iLetter.debug 0x00000001104e480e _Main + 846 (/#main:1905)
26 iLetter.debug 0x00000001104c8e33 main + 19
27 libdyld.dylib 0x00007fff703c33d5 start + 1
You see the call to quitRightNow, which goes into lib system_c but then back to XojoFramework, just as it does if I quit in the ordinary way. So it looks like Xojo always manages to keep control of the exiting process.
I could have a look at this and see what I can find IF you want
That would be most kind, thanks.
Personally I do it from app.cancelClose, then I manually go through and check the cancelClose on each window before I terminate.
Whaoā¦ Never seen this happening before. Itās like thereās something sending Xojo a message on close. I think Iāve seen an option for this, but I canāt recall where. Iād have to do some digging.