JBildstein/SpiderEye

Crashes on MacOS Catalina

Rjvs opened this issue · 11 comments

Rjvs commented

Describe the bug
Clone SpiderEye, issue dotnet run in either of the example folders, result is a dialog reporting that SpiderEye quit unexpectedly. Running from debugger shows exit code 11.

To Reproduce
Steps to reproduce the behavior:

  1. Change directory to any SpiderEye example folder
  2. cd App.Mac
  3. dotnet run
  4. See error

Expected behavior
See the example, as I do on Win10 doing the same thing.

Screenshots
There is literally nothing to see.

Environment:

  • OS: MacOS Cataline 10.15.3
  • SpiderEye Version: afd94fa (head)
Rjvs commented

@JBildstein specifically, dotnet is exploding when you call the run selector on [NSApplication sharedApplication] in CocoaApplication.Run().

thank you for the report!

I'm currently trying to get Catalina to work in a VM but it seems I need to wait for a VirtualBox update first.

In the meantime, perhaps you can try and get a stacktrace or some more details on the error.
When you get the dialog that it crashed unexpectedly, click on the report error button.
Then it should show you a window with a stacktrace and some more infos on the error. Please copy/paste that and then you can cancel the error report.

Rjvs commented

The stack trace is below;

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               	0x00007fff646903e5 class_conformsToProtocol + 312
1   libobjc.A.dylib               	0x00007fff6469028b -[NSObject conformsToProtocol:] + 47
2   com.apple.AppKit              	0x00007fff2bbe91d4 -[NSApplication(NSTouchBarFinder) NS_touchBarProviders] + 403
3   com.apple.AppKit              	0x00007fff2bbea1fa _NSTouchBarFinderGatherProvidersForContainer + 64
4   com.apple.AppKit              	0x00007fff2bbea32c _NSTouchBarFinderGatherProvidersForContainer + 370
5   com.apple.AppKit              	0x00007fff2bbea32c _NSTouchBarFinderGatherProvidersForContainer + 370
6   com.apple.AppKit              	0x00007fff2bbe9870 ___NSTouchBarFinderSetNeedsUpdateOnMain_block_invoke + 240
7   com.apple.AppKit              	0x00007fff2bbea135 ___NSRunLoopObserverCreateWithHandler_block_invoke + 41
8   com.apple.CoreFoundation      	0x00007fff2e3610ee __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
9   com.apple.CoreFoundation      	0x00007fff2e361014 __CFRunLoopDoObservers + 457
10  com.apple.CoreFoundation      	0x00007fff2e35fc0e CFRunLoopRunSpecific + 558
11  com.apple.HIToolbox           	0x00007fff2ceb565d RunCurrentEventLoopInMode + 292
12  com.apple.HIToolbox           	0x00007fff2ceb52a9 ReceiveNextEventCommon + 356
13  com.apple.HIToolbox           	0x00007fff2ceb5127 _BlockUntilNextEventMatchingListInModeWithFilter + 64
14  com.apple.AppKit              	0x00007fff2b525ba4 _DPSNextEvent + 990
15  com.apple.AppKit              	0x00007fff2b524380 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
16  com.apple.AppKit              	0x00007fff2b51609e -[NSApplication run] + 658
17  ???                           	0x0000000108b631b3 0 + 4441125299
18  ???                           	0x0000000108b7a1a1 0 + 4441219489
19  ???                           	0x0000000108b7a14e 0 + 4441219406
20  ???                           	0x0000000108b795e3 0 + 4441216483
21  ???                           	0x0000000108b6a48f 0 + 4441154703
22  ???                           	0x0000000108b5ffae 0 + 4441112494
23  libcoreclr.dylib              	0x00000001020f3c3b CallDescrWorkerInternal + 124
24  libcoreclr.dylib              	0x0000000101f40029 MethodDescCallSite::CallTargetWorker(unsigned long const*, unsigned long*, int) + 1657
25  libcoreclr.dylib              	0x0000000101e07ef6 RunMain(MethodDesc*, short, int*, PtrArray**) + 726
26  libcoreclr.dylib              	0x0000000101e08268 Assembly::ExecuteMainMethod(PtrArray**, int) + 408
27  libcoreclr.dylib              	0x0000000101e48678 CorHost2::ExecuteAssembly(unsigned int, char16_t const*, int, char16_t const**, unsigned int*) + 504
28  libcoreclr.dylib              	0x0000000101d80052 coreclr_execute_assembly + 226
29  libhostpolicy.dylib           	0x0000000101cf55d7 0x101ce4000 + 71127
30  libhostpolicy.dylib           	0x0000000101cf6438 0x101ce4000 + 74808
31  libhostfxr.dylib              	0x0000000101cb2a9f 0x101c89000 + 170655
32  libhostfxr.dylib              	0x0000000101cb1d92 0x101c89000 + 167314
33  libhostfxr.dylib              	0x0000000101cadd9a 0x101c89000 + 150938
34  SpiderEye.Example.Simple      	0x0000000101c54724 0x101c49000 + 46884
35  SpiderEye.Example.Simple      	0x0000000101c54a3f 0x101c49000 + 47679
36  libdyld.dylib                 	0x00007fff65a057fd start + 1

Thanks!

It looks like it expects the app to support the touchbar. It may be enough if I implement NSTouchBarProvider in the app delegate but I'll have to try (or perhaps you have to, since I don't have a touchbar).
I'll put something together and let you know.

For reference: Apple Docs on Touchbar

And it seems I'm not the only one with that problem:

We're having no issues with SpiderEye on macOS, even on Catalina here.

Well after I understood the fact that even with the addition of the SynchronizationContext macOS can't be convinced to just run SpiderEye and thus the NSApplication on a thread that isn't the first thread. Due to us wanting to use the generic host I tried to just spin up a thread (setting it to be an STA thread on Windows), then initialize the SpiderEye stuff on there... Just didn't work on macOS. So instead we've switched it around to just make the host run on another thread instead of the host spawning SpiderEye. This makes it a bit dirty as I would have liked to basically roll with a SpiderEye IHostLifetime, but at least it works now 😄


That being said I just got confirmation from my colleague who tested on macOS: We didn't test on a Mac with a touchbar yet! So I believe you're onto something there.

thank you for the additional feedback @bddckr, happy to hear it works well for you.
That seems to further indicate that the touchbar is the issue. I just read that there is a touchbar simulator in XCode and I'll try and see if I can reproduce it with that or perhaps make the touchbar work with SpiderEye.

@bddckr as for the generic host, feel free to create a new issue for it, maybe we can figure out what the problem is. It should work, but I know from another project that macOS has funny ideas about the main thread sometimes.

Rjvs commented

I've tried setting isAutomaticCustomizeTouchBarMenuItemEnabled to false with no change, so I suspect that it is a matter of implementing the TouchBar handlers.

I'm happy to run any tests for you but if you want to test TouchBar locally, you might be able to run Touché to simulate it and cause the callbacks.

So I received the VirtualBox update now and got Catalina running.

The simulator in XCode works well and with it I'm able to replicate the bug, both in Catalina and Mojave. If anyone wants to try it too, just start XCode and in the menu select "Window->Show Touch Bar" in XCode 10 or "Window->Touch Bar->Show Touch Bar" in XCode 11.

I'm currently trying to implement NSTouchBarProvider in the app delegate but it doesn't seem to work so far. Somehow my implementation of the touchBar property (the only member of NSTouchBarProvider) doesn't seem to satisfy the conformsToProtocol check. I have to leave it for now and try again tomorrow.

Found the problem(s) and fixed it. @Rjvs it'd be great if you could try if it works for you as well. Note that you have to start the playground project and not the example. The examples use the NuGet packages and they are not updated yet. If you start the playground project without running the Angular dev server you'll just see a blank window but it'll be enough to check if it works.

To fix it I had to fix a few other things first:

  • to get the NSTouchBarProvider protocol the call has to be made into AppKit.framework and not into libobjc or it'll return null
  • adding a protocol to a class definition also checks if the protocol is implemented, so it has to be done when finishing the class definition instead of at the beginning. This was never a problem before because all protocol members were optional.
  • Some protocols are not available at runtime (like NSApplicationDelegate) and return null. That's not an issue somehow, but when adding a null protocol to a class definition it seems to mess up the conformsToProtocol check for other protocols.

With all that in place, adding support for the touch bar is just a matter of setting NSResponder as the base class for the app delegate instead of NSObject and adding the NSTouchBarProvider protocol. NSResponder already implements NSTouchBarProvider so that solves it.

Rjvs commented

Excellent work @JBildstein I can confirm that it works on my hardware.

wonderful! thank you for the confirmation @Rjvs. I'll do and update of the NuGet packages in a little while, want to add a few things first.