So I am in the process of moving previous console helper classes into preemptive threaded ones. These classes address measurement instruments; sometimes via Serial, sometimes through supplier APIs. For the latter ones I found DeclareLibraryMBS to be a great help; and basically the whole model works really nicely. But whenever I used such a thread class in the desktop app that’s containing it, during app quit I will always get an exception on what is very probably the thread class that was definitely stopped before.
This specific API is troublesome anyway: It is not UB on macOS, so I have to build the app for Intel. It is bound to a handful of other libraries, some of them QT, which are not easy to include: If I import them into the app before the internal code signing, Xojo will crash when it finds it cannot sign them. So I have another build step after signing to import them, and AppWrapper luckily does not encounter any issues then. Don’t know if that’s related … Crash report always looks like
Thread 7 Crashed:: EthernetThread
0 libRosettaRuntime 0x1118fb024 0x1118ad000 + 319524
1 ??? 0x109d987e0 ???
2 ??? 0x100000084 ???
3 QtCore 0x135f51849 0x135f2f000 + 141385
4 libsystem_pthread.dylib 0x7ff805cdb253 _pthread_start + 99
5 libsystem_pthread.dylib 0x7ff805cd6bef thread_start + 15
and main thread will always look like
Error Formulating Crash Report:
PC register does not match crashing frame (0x0 vs 0x1118FB024)
Thread 0:: Dispatch queue: com.apple.main-thread
0 runtime 0x7ff7ffca6d68 0x7ff7ffca3000 + 15720
1 runtime 0x7ff7ffcafad4 0x7ff7ffca3000 + 51924
2 runtime 0x7ff7ffcad324 0x7ff7ffca3000 + 41764
3 ??? 0x1098ac514 ???
4 ??? 0x1099b4bf8 ???
5 myApp.debug 0x103683f0f DeclareLibraryMBS.__exit%%o + 31
6 XojoFramework 0x112bc8113 0x11295f000 + 2527507
7 XojoFramework 0x112bc7ea5 RuntimeUnlockObject + 107
8 XojoFramework 0x112aca8ab RuntimeViewWindow::Close() + 253
9 XojoFramework 0x112accb41 RuntimeView::UnifiedClose(bool) + 529
10 XojoFramework 0x112abe4af 0x11295f000 + 1438895
11 XojoFramework 0x112c268fe IterateWindowList(unsigned char ()(Window, void*), void*) + 1176
12 XojoFramework 0x112abe368 TestApplicationQuit() + 111
13 XojoFramework 0x112abe504 ApplicationQuit(long long, unsigned char) + 13
Any ideas what might be the cause and how to fix the exception?
Pinging @Christian_Schmitz as I always see DeclareLibraryMBS.exit in the vicinity of this bug.
Addition: The same happens if I try to Nil the DeclareLibraryMBS instance when the thread is quit:
PC register does not match crashing frame (0x0 vs 0x109E65D5C)
Crashed Thread: 14 EthernetThread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000135416b20
Exception Codes: 0x0000000000000001, 0x0000000135416b20
Main thread:
Thread 0:: Dispatch queue: com.apple.main-thread
0 ??? 0x7ff895e6ea84 ???
1 libsystem_kernel.dylib 0x7ff805c9c12e __psynch_mutexwait + 10
2 libsystem_pthread.dylib 0x7ff805cd8b54 _pthread_mutex_firstfit_lock_wait + 78
3 libsystem_pthread.dylib 0x7ff805cd6940 _pthread_mutex_firstfit_lock_slow + 214
4 libc++.1.dylib 0x7ff805c2082d std::__1::recursive_mutex::lock() + 9
5 XojoFramework 0x112caae65 RuntimeUnlockObject + 43
6 MBS_Main_NSBase_Plugin_21145.dylib 0x115755921 -[MBSREALobjectWrapper dealloc] + 65
7 libobjc.A.dylib 0x7ff805911092 AutoreleasePoolPage::releaseUntil(objc_object**) + 186
8 libobjc.A.dylib 0x7ff80590e3ba objc_autoreleasePoolPop + 235
9 CoreFoundation 0x7ff805d817d9 _CFAutoreleasePoolPop + 22
10 Foundation 0x7ff806d10967 -[NSAutoreleasePool release] + 131
11 XojoFramework 0x112b9cc82 AutoreleasePool::~AutoreleasePool() + 20
12 XojoFramework 0x112cb0823 0x112a42000 + 2549795
Thread 14 Crashed:: EthernetThread
0 0x109e65d5c ???
1 QtCore 0x136015849 0x135ff3000 + 141385
2 libsystem_pthread.dylib 0x7ff805cdb253 _pthread_start + 99
3 libsystem_pthread.dylib 0x7ff805cd6bef thread_start + 15
While another thread that drives a serial instrument will quit just nicely:
Thread 12:
0 libRosettaRuntime 0x1119dec9c 0x111990000 + 322716
1 0x109e66304 ???
2 ??? 0x100000114 ???
3 XojoFramework 0x112cab31e RuntimeLockUnlockObjects + 91
4 myApp.debug 0x104e39a18 CCThreadXDSX.Event_subclass_DeInitialize%%o + 216 (/CCThreadXDSX:28)
5 myApp.debug 0x104e2bb59 CCThreadMeasurementDevice.Event_subclass_DeInitialize%%o + 233 (/CCThreadMeasurementDevice:6)
I cannot catch the exception with normal Xojo means. Any way I could do so?
This hints me something trying to touch some GUI functions (weird, QT?) and probably tied to some window that was closed, and you are using a non-GUI build? Also seems a code under Rosetta.
Does it run ok native without Rosetta or it also crashes?
Sadly, the API is only available Intel based, so there is no native running. And no, it’s inside a Desktop app, and as written the unhandled (or unhandleable) exception does also appear when I nil the LibraryMBS object when not quitting the app, so all windows are available at this stage.
It’s a stupidity the API is bound to Qt. But without the libraries being available too, I could not even build a console app using it. There are no API functions that would open a window or some other control, it’s purely a device control API.
… and QTCore is a non-GUI framework that provides an object communication model. But it is definitely somewhat fishy as Xojo will crash during signing stage when it’s imported into the app bundle at this stage.
Well, your crashes appear after closes (including a RuntimeViewWindow::Close() + 253) and releases (AutoreleasePool::~AutoreleasePool() + 20), and that makes me think on some loss of sync with threads trying to use released content.
1 Like
I agree it looks this way, but there is nothing that would do that. In fact, the crash appears immediately when the LibraryMBS object is released, without any further steps and even if I switch the thread type to cooperative.
Think I should just declare this library and release it completely without a thread and check if that will crash the app too …
Like so often, talking and getting feedback helps a lot, even if the bug resides in a different place.
Creating and releasing a DeclareLibraryMBS with that API did work unthreaded without exception, and your words about threads getting out of sync lead me to the reason: In Window.CancelClose I am checking if every instrument is disconnected, and I mixed up some properties of my own class, which lead to the code trying to stop an already stopped thread. Why that transferred to Qt I have no clue, but fixing my bug stopped crashing the app.
Thanks a lot for your feedback, Rick!
1 Like