Crash during calculation

Hi all,
I need some Guru’s help checking down an unexpected crash of my App.
The app is calculating in a thread, with #Pragma BackgroundTasks False, using DelayMBS when needed to yield time to the main thread for refreshing GUI and checking for User Cancellation.
All of that works like a charm, except if I type in any key of the keyboard (but modifiers). Doing that kills immediately the App and the error is not handled by the UnhandledException event.

Here is the dump of the crashed thread, made in the Apple’s Report:

Blockquote

Thread 6 Crashed:
0 libdispatch.dylib 0x7ff801d76b66 _dispatch_assert_queue_fail + 102
1 libdispatch.dylib 0x7ff801d76b00 dispatch_assert_queue + 148
2 HIToolbox 0x7ff80ba73230 islGetInputSourceListWithAdditions + 119
3 HIToolbox 0x7ff80ba7573d isValidateInputSourceRef + 90
4 HIToolbox 0x7ff80ba75605 TSMGetInputSourceProperty + 30
5 HIToolbox 0x7ff80ba93d19 GetCurrentInputSourceKeyboardProperties + 141
6 HIToolbox 0x7ff80ba936ed TSMTranslateKeyEvent + 355
7 HIToolbox 0x7ff80ba9650f TSMProcessRawKeyCode + 95
8 HIToolbox 0x7ff80bad60e3 IsUserCancelEventRef + 167
9 HIToolbox 0x7ff80bad5ee2 CheckEventQueueForUserCancel + 100
10 XojoFramework 0x105dbd7f6 getUserCancelled + 9
11 Factorielle 4.4 OS X.debug 0x104d4543f REALbasic.UserCancelled%b% + 15
12 Factorielle 4.4 OS X.debug 0x104e20b44 Calcul.Event_Run%%o + 12628 (/Calcul:190)
13 XojoFramework 0x105ec9754 0x105c53000 + 2582356
14 XojoFramework 0x105d8a766 0x105c53000 + 1275750
15 libsystem_pthread.dylib 0x7ff801f161d3 _pthread_start + 125
16 libsystem_pthread.dylib 0x7ff801f11bd3 thread_start + 15

Thread 6 crashed with X86 Thread State (64-bit):
rax: 0x6196fdb1196b000b rbx: 0x00006000011a3680 rcx: 0x0000000000000007 rdx: 0x00000000dd416065
rdi: 0x00000000dd416000 rsi: 0x0000000000000064 rbp: 0x0000700006fee220 rsp: 0x0000700006fee210
r8: 0x0000000000000080 r9: 0x000000000000007f r10: 0x0000000000003200 r11: 0x0000600003df6844
r12: 0x0000600003f99f80 r13: 0x00000000ffffff40 r14: 0x0000700006fee328 r15: 0x0000000000000000
rip: 0x00007ff801d76b66 rfl: 0x0000000000010206 cr2: 0x00000001980a30d0

Logical CPU: 2
Error Code: 0x00000000
Trap Number: 6

Thread 6 instruction stream:
49 89 f9 48 8d 5d f0 48-c7 03 00 00 00 00 48 8d I…H.].H…H.
05 83 a3 03 00 48 8d 0d-a8 67 03 00 85 f6 48 0f …H…g…H.
45 c8 4c 8b 47 48 4d 85-c0 4c 0f 44 c0 48 8d 35 E.L.GHM…L.D.H.5
2a 67 03 00 48 8d 15 58-67 03 00 48 89 df 31 c0 *g…H…Xg…H…1.
e8 27 37 03 00 48 8b 1b-48 8d 3d 7a 67 03 00 48 .'7…H…H.=zg…H
89 de 31 c0 e8 8c e8 02-00 48 89 1d 42 29 b0 41 …1…H…B).A
[0f]0b 55 48 89 e5 48 8b-07 0f b6 40 28 48 8d 48 …UH…H…@(H.H <==
ed 48 83 f9 fd 76 72 48-8b 47 38 65 33 04 25 18 .H…vrH.G8e3.%.
00 00 00 a9 fc ff ff ff-74 58 65 48 8b 0c 25 a0 …tXeH…%.
00 00 00 48 85 c9 0f 94-c2 74 41 48 39 f9 74 3c …H…tAH9.t<
65 48 8b 04 25 a8 00 00-00 48 8b 51 18 48 85 c0 eH…%…H.Q.H…
74 0f 48 8b 30 48 85 d2-74 0b 48 39 f1 75 0d eb t.H.0H…t.H9.u…

Blockquote

Is it enough to understand what’s going on? Don’t hesitate to let me know if you need other part(s) of the report. I’m unable to understand such a report!

Mac OS 13.5, French language, Xojo 2023r1.1

TIA for any help
Jean-Luc

Bonjour Jean-Luc,

You should always have a function to handle unhandled exception. This way you can parse the unhandled exception data and display a message to the screen with more relevant information that will tell you in which method the exception occured, the type of exception and it’s message etc. As you can see, the crash report is not easy to understand,

Since a crash log is quite large, I suggest attaching it to a message, this way those who can make their way in it will be able to tell you more.

My guess is that DelayMBS is causing some weird re-entrancy issue which macOS doesn’t like.

Have you tried removing it?

Also think you should try avoiding DelayMBS, and just try using plain old Thread.Yield(milliseconds)

thread.YieldToNext() or myThread.sleep(msec), perhaps.

Tim you are correct, apparently I was remembering (misremembering) the old API1 names.

In fact, in API2 you also have

AddUserInterfaceUpdate (data As Dictionary)

Which might be ideal for @Jean-Luc_ARNAUD as the goal is to do UI updates.

Question: does AddUserInterfaceUpdate do a Yield or Sleep automatically, or do you have to Yield or Sleep explicitely?

The docs say it triggers an event on the main thread, so it must yield automatically.

You should always have a function to handle unhandled exception.

Bonjour Gilles,
Thanks for replying. Actually, I have such a function, based on an UnHandledException Event, as I wrote it:

Doing that kills immediately the App and the error is not handled by the UnhandledException event.

Unfortunately, it does not intercept the error, the app is killed.
Thanks for the suggestion to attach the crash log as a message.

Many thanks to Kevin, Mike and Tim. I will test replacing DelayMBS with thread.YieldToNext() or myThread.sleep(msec) and will let you know what happens.

I tested both commands Thread.YieldToNext() and Thread.sleep(msec), same error. So DelayMBS is not responsible for it. Nevertheless, from today, I will use Thread.Sleep(1)!
In addition, given that DelayMBS is not guilty, I tested another part of my code where I check if the User has cancelled the calculation:

If UserCancelled Or CancelFlag Then
CancelFlag=True ’ Set it to True if UserCancelled
System.Beep
Exit
End If

Where UserCancelled is true if the User has pressed Escape (on Windows or Linux) or Command-period (on macOS), and CancelFlag is a Boolean set true in a “Interrupt” button of the GUI.
UserCancelled is responsible for the App crash!
Testing only CancelFlag, I have no more crash.

Now, I’d like to know why calling UserCancelled in a thread crashes the app. A Xojo bug? Something like a silent ThreadAccessingUI error?

When you call “userCancelled” it enters the Xojo framework and calls HIToolbox CheckEventQueueForUserCancel. This is a really old Apple API that uses Apple’s deprecated Carbon framework, the documentation states the API is NOT THREAD SAFE.

If you remove this, perhaps the crashes will stop. But what about the user cancelling the operation? If you have a window present, display a “Cancel” button and react to that. If not you could use declares to set-up a NSEvent monitor to capture the key presses and then react to that.

However, displaying a dialog with a cancel button is the most user friendly and the option I would recommend the most.

2 Likes

Good point: if your background thread is well-behaved, then your foreground UI can do all the normal things to check for cancellation, such as having a big “Cancel” button that the user can click, or responding to KeyDown events and looking for the ESC or Command-. keystrokes, etc.

1 Like