Description
As discussed in #156, it seems that blocks cannot be properly serialized to remote objects, when attempting a remote method call in a +load
method, due to load order woes.
The code linked in the other issue shows that __attribute__((constructor))
is used, which is ordered later in the start chaing, after +load
methods.
Moving the code to +load
is also not the best solution, as +load
are also subject to call order issues, as I recently discovered. I've settled on nasty hacks in my case. But those hacks aren't suitable here, as the code is in a class category.
The result is that when a block is called from the remote process, it is not serialized correctly on the client side (because the above-linked code has not executed yet), and an exception is raised +[NSInvocation _invocationWithMethodSignature:frame:]: method signature argument cannot be nil
in:
frame #0: 0x00007fff503b5af0 libobjc.A.dylib`objc_exception_throw
frame #1: 0x00007fff23b9bc83 CoreFoundation`+[NSInvocation _invocationWithMethodSignature:frame:] + 355
* frame #2: 0x0000000103e6efb8 DetoxHelper`__38+[EDOInvocationRequest requestHandler]_block_invoke(.block_descriptor=0x0000600003a7cd20, originalRequest=0x0000600002174540, service=0x0000600001f78540) at EDOInvocationMessage.m:313:34
frame #3: 0x0000000103e6bb1e DetoxHelper`-[EDOExecutor edo_handleMessage:](self=0x0000600003a7ce10, _cmd="edo_handleMessage:", message=0x0000600003a68060) at EDOExecutor.m:143:16
frame #4: 0x0000000103e6ac2f DetoxHelper`-[EDOExecutor runWithBlock:](self=0x0000600003a7ce10, _cmd="runWithBlock:", executeBlock=0x0000000103e7c660) at EDOExecutor.m:88:5
frame #5: 0x0000000103e7bca9 DetoxHelper`+[EDOClientService sendSynchronousRequest:onPort:withExecutor:](self=EDOClientService, _cmd="sendSynchronousRequest:onPort:withExecutor:", request=0x000060000216c400, port=0x0000600003478180, executor=0x0000600003a7ce10) at EDOClientService.m:273:9
frame #6: 0x0000000103e66bfb DetoxHelper`-[EDOObject(self=0x0000600002178700, _cmd="edo_forwardInvocation:selector:returnByValue:", invocation=0x0000600002172d80, selector="waitForIdleWithCompletionHandler:", returnByValue=NO) edo_forwardInvocation:selector:returnByValue:] at EDOObject+Invocation.m:89:32
frame #7: 0x0000000103e669f9 DetoxHelper`-[EDOObject(self=0x0000600002178700, _cmd="forwardInvocation:", invocation=0x0000600002172d80) forwardInvocation:] at EDOObject+Invocation.m:66:3
frame #8: 0x00007fff23b9d566 CoreFoundation`___forwarding___ + 838
frame #9: 0x00007fff23b9f6c8 CoreFoundation`__forwarding_prep_0___ + 120
frame #10: 0x0000000103e65300 DetoxHelper`__23-[DetoxManager connect]_block_invoke(.block_descriptor=0x0000000103e9b4e0) at DetoxManager.m:58:3
frame #11: 0x00007fff511fc7f9 libdispatch.dylib`_dispatch_client_callout + 8
frame #12: 0x00007fff511fda25 libdispatch.dylib`_dispatch_once_callout + 20
frame #13: 0x0000000103e65184 DetoxHelper`-[DetoxManager connect] [inlined] _dispatch_once(predicate=0x0000000103ea7830, block=0x0000000103e651b0) at once.h:84:3
frame #14: 0x0000000103e65169 DetoxHelper`-[DetoxManager connect](self=0x000060000347c780, _cmd="connect") at DetoxManager.m:54
frame #15: 0x0000000103e65036 DetoxHelper`+[DetoxManager load](self=DetoxManager, _cmd="load") at DetoxManager.m:36:3
frame #16: 0x00007fff503bcdf0 libobjc.A.dylib`load_images + 1226
frame #17: 0x0000000103dc2d79 dyld_sim`dyld::notifySingle(dyld_image_states, ImageLoader const*, ImageLoader::InitializerTimingList*) + 418
frame #18: 0x0000000103dcf970 dyld_sim`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 438
frame #19: 0x0000000103dce786 dyld_sim`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 188
frame #20: 0x0000000103dce826 dyld_sim`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 82
frame #21: 0x0000000103dc3046 dyld_sim`dyld::initializeMainExecutable() + 129
frame #22: 0x0000000103dc70fc dyld_sim`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 3831
frame #23: 0x0000000103dc21cd dyld_sim`start_sim + 122
frame #24: 0x00000001094eb6b7 dyld`dyld::useSimulatorDyld(int, macho_header const*, char const*, int, char const**, char const**, char const**, unsigned long*, unsigned long*) + 2308
frame #25: 0x00000001094e9375 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 818
frame #26: 0x00000001094e4227 dyld`dyldbootstrap::start(dyld3::MachOLoaded const*, int, char const**, dyld3::MachOLoaded const*, unsigned long*) + 453
frame #27: 0x00000001094e4025 dyld`_dyld_start + 37