I'm facing a weird situation. Everytime a try to dlopen my library the application totally freezes. Does anyone have faced the same issue or have some suggestion?
dlopen freezes application
* frame #0: 0x0000000189a7370c libsystem_kernel.dylib`__ulock_wait + 8
frame #1: 0x00000001898ef5a0 libdispatch.dylib`_dlock_wait + 56
frame #2: 0x00000001898ef4d0 libdispatch.dylib`_dispatch_once_wait + 120
frame #3: 0x0000000189b4ab2c CoreFoundation`CFURLCopyResourcePropertyForKey + 284
frame #4: 0x0000000192945350 HIToolbox`___HIMagnifiedMode_block_invoke + 104
frame #5: 0x00000001898eebac libdispatch.dylib`_dispatch_client_callout + 20
frame #6: 0x00000001898f0454 libdispatch.dylib`_dispatch_once_callout + 32
frame #7: 0x00000001926e88bc HIToolbox`_HIMagnifiedMode + 64
frame #8: 0x000000018c69bc08 AppKit`-[NSScreen backingScaleFactor] + 40
frame #9: 0x000000018c69b450 AppKit`_NSScreenConfigurationUpdateWithSharedInfo + 2072
frame #10: 0x000000018c699428 AppKit`___NSScreenConfigurationEnsureInitialUpdateOccurred_block_invoke + 124
frame #11: 0x00000001898eebac libdispatch.dylib`_dispatch_client_callout + 20
frame #12: 0x00000001898f0454 libdispatch.dylib`_dispatch_once_callout + 32
frame #13: 0x000000018c6e042c AppKit`+[_NSScreenConfiguration latestScreens] + 280
frame #14: 0x000000018c6e01d8 AppKit`+[NSScreen mainScreen] + 32
It looks like I've been trapped by an eternal lock_wait...
Unfortunately I can’t read your backtrace )-:
What I’d like to see here is a crash report. If you run your app outside of Xcode, does it hang in the same way? If so, send it a SIGABRT
from Terminal:
% kill -ABRT 123
where 123
is your process ID. Then take the resulting crash report and post it here, using the instructions from Posting a Crash Report.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I attached the crash report
Thanks.
The crash report confirms that this is a variant of a problem that crops up from time-to-time (for example, see this thread). Let’s start with your main thread (thread 0), and specifically this snippet:
2 libdispatch.dylib … _dispatch_once_wait + 120
3 CoreFoundation … CFURLCopyResourcePropertyForKey + 284
4 HIToolbox … ___HIMagnifiedMode_block_invoke + 104
…
14 AppKit … +[NSScreen mainScreen] + 32
15 libmyguilib.dylib … DispatchToImport + 160
…
21 libmyguilib.dylib … Myguilib::initialization() + 64
22 dyld … invocation function for block in dyld4
::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 164
The dynamic linker is in the process of starting up your app and has called the initialiser function (frame 22) for libmyguilib.dylib
(frame 21). That initialiser is doing stuff and eventually calls through to +[NSScreen mainScreen]
(frame 14). Deep in that code (frame 4) there’s a called to CFURLCopyResourcePropertyForKey
(frame 3) which has blocked indefinitely inside a dispatch_once
.
The backtrace of thread 1 shows why it’s stuck:
0 libsystem_kernel.dylib … __ulock_wait + 8
1 libsystem_platform.dylib … _os_unfair_lock_lock_slow + 228
2 dyld … dyld4::APIs::dlopen_from(char const*, int,
void*) + 236
3 CoreFoundation … __CFLookupCoreServicesInternalFunction + 76
4 CoreFoundation … ____CFCoreServicesInternal
__FSURLCopyResourcePropertyForKey_block_invoke + 24
5 libdispatch.dylib … _dispatch_client_callout + 20
6 libdispatch.dylib … _dispatch_once_callout + 32
7 CoreFoundation … CFURLCopyResourcePropertyForKey + 284
8 CoreFoundation … ____CFRunLoopSetOptionsReason_block_invoke_5 + 180
9 libdispatch.dylib … _dispatch_call_block_and_release + 32
10 libdispatch.dylib … _dispatch_client_callout + 20
11 libdispatch.dylib … _dispatch_root_queue_drain + 964
12 libdispatch.dylib … _dispatch_worker_thread2 + 164
13 libsystem_pthread.dylib … _pthread_wqthread + 228
14 libsystem_pthread.dylib … start_wqthread + 8
It’s hard to illustrate exactly what’s going on here (I think some symbols are not being symbolicated properly) but the upshot is that the block called by dispatch_once
(frame 7) is trying to dynamically load a symbol from another framework (frames 3 and 2) which has blocked against the dynamic linker’s global lock.
This is a classic deadlock. Thread 0 is stuck waiting for thread 1 to finish but thread 1 can’t finish because thread 0 is holding a lock that it needs to acquire.
Which brings me to the conclusion from the above-mentioned thread:
-
We generally discourage folks from creating library initialisers, so frame 21 of thread 0 is less than ideal.
-
However, the work being done by that initialiser isn’t exactly onerous.
+[NSScreen mainScreen]
should be fairly lightweight. -
This is definitely a problem that Apple should investigate, so I encourage you to file a bug about this. Make sure to attach a sysdiagnose log taken while the process is deadlocked. Also, if you can attach the code necessary to reproduce the problem that’d be grand.
Please post your bug number, just for the record.
-
As to how you work around this, I suspect that adding a call to
+[NSScreen mainScreen]
to the start of yourmain
function (thread 0 frame 34) should avoid the problem. That’ll get all theNSScreen
initialisation done outside of the context of the dynamic linker’s global lock.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"