dlopen freezes application

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?

thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGTERM

  * 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 your main function (thread 0 frame 34) should avoid the problem. That’ll get all the NSScreen 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"

dlopen freezes application
 
 
Q