I did some research on how Apple implemented Objective-C exceptions and CoreFoundation on iOS (iOS 6.1.3 on iPhone 4S) and I found something that we can use.
If you want me to test anything, please reply to this Email and I will test it
for you. I have three devices to test: iOS 6.1.3 on iPhone 4S (armv7) and iPad
2 (armv7), as well as OS X 10.8.3 on my MacBook Pro (x86-64 and i386 both). I
may also be able to borrow an iPad 4 for testing (iOS 6.1.2, armv7s)
1) Apple's libobjc depend on LLVM's libc++abi (in Linux, it should be
libsupc++). Not only Apple did that to allow proper Objective-C++, but also
something more.
When an Objective-C exception is triggered and not caught in Objective-C code,
it will be raised as a C++ exception. This happens no matter if your code have
C++ or not. Here is an crash log explaining this: (MobileDeuterium is the app I
wrote. It have zero C++ in it.)
Incident Identifier: 3B2E3282-1537-4261-A77A-7931E8898F06
CrashReporter Key: 821361952184b8795bbbd7dd4b9db7b36d3a208a
Hardware Model: iPhone4,1
Process: MobileDeuterium [18922]
Path:
/var/mobile/Applications/C9064A00-2DB5-437A-9B0C-AC055C1F70A1/MobileDeuterium.app/MobileDeuterium
Identifier: MobileDeuterium
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2013-05-26 08:45:19.713 +0800
OS Version: iOS 6.1.2 (10B146)
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Crashed Thread: 4
--- Lines truncated ---
Thread 4 name: Dispatch queue: com.apple.root.default-priority
Thread 4 Crashed:
0 libsystem_kernel.dylib 0x39c5e350 __pthread_kill + 8
1 libsystem_c.dylib 0x39bd511e pthread_kill + 54
2 libsystem_c.dylib 0x39c1196e abort + 90
3 libc++abi.dylib 0x391afd4a abort_message + 70
4 libc++abi.dylib 0x391acff4 default_terminate() + 20
5 libobjc.A.dylib 0x39760a74 _objc_terminate() + 144
6 libc++abi.dylib 0x391ad078 safe_handler_caller(void
(*)()) + 76
7 libc++abi.dylib 0x391ad110 std::terminate() + 16
8 libc++abi.dylib 0x391ae50e __cxa_throw + 118
9 libobjc.A.dylib 0x397609ba objc_exception_throw + 90
10 CoreFoundation 0x31a46e02 -[NSObject(NSObject)
doesNotRecognizeSelector:] + 166
11 CoreFoundation 0x31a4552c ___forwarding___ + 388
12 CoreFoundation 0x3199cf64 _CF_forwarding_prep_0 + 20
13 MobileDeuterium 0x0009ba36 0x97000 + 18998
14 libdispatch.dylib 0x39b7811c
_dispatch_call_block_and_release + 8
15 libdispatch.dylib 0x39b7c95c _dispatch_root_queue_drain +
248
16 libdispatch.dylib 0x39b7cabc _dispatch_worker_thread2 + 80
17 libsystem_c.dylib 0x39baca0e _pthread_wqthread + 358
18 libsystem_c.dylib 0x39bac8a0 start_wqthread + 4
--- Lines truncated ---
Note: iPhone4,1 is the internal identifier of iPhone 4S.
2) Toll-Free Bridging is a cross-effort of both Foundation and CoreFoundation.
Try compile this code on OS X:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
int main(void)
{
@autoreleasepool
{
CFStringRef string = CFSTR("hello, world");
NSString *string_objc = (__bridge NSStirng *)string;
NSLog("Class: %@", NSStringFromClass([string_objc class]));
CFRelease(string);
}
return 0;
}
To compile: xcrun clang test.m -o test -framework Foundation -framework
CoreFoundation -Wall -fobjc-arc
The output will be: "Class: __NSCFString" and one explanation of that: it is a
CoreFoundation object toll-free bridged over into Foundation.
I saw this in my original ohttpd (on OS X) so here is my guess on how that
worked:
1) All CoreFoundation objects have a complete Objective-C object structure, and
its isa pointer is assigned to its Objective-C companion class. Given that
Apple does not put retain counts in the object itself, this structure is only
an isa pointer.
2) All CoreFoundation objects have a more or less functional Objective-C
companion class.
3) For toll-free bridged objects, this companion class is a subclass of its
public class cluster and have at least all important methods overridden with
glue code that call into CoreFoundation functions.
4) For non-toll-free bridged objects, this companion class is a subclass of
NSObject or NSProxy and implements only memory management methods.
5) CFRetain and CFRelease are stubs that call -[id<NSObject> retain] and
-[id<NSObject> release]. CoreFoundation does not manage its memory directly
using its own functions. Instead, all clean-ups are done by implementing a
-[id<NSObject> dealloc] method in its companion Objective-C class.
6) When a Foundation object is passed into a CoreFoundation function as a
parameter and the object is not subject to changes in the procedure, it is
converted into its CoreFoundation counterpart, probably using -[id<NSCopying>
copy] method.
7) When a Foundation object is passed into a CoreFoundation function as a
parameter that will change the object itself, the function will call
corresponding Foundation method(s) directly or via other CoreFoundation
functions.
signature.asc
Description: Message signed with OpenPGP using GPGMail
_______________________________________________ Gnustep-dev mailing list [email protected] https://lists.gnu.org/mailman/listinfo/gnustep-dev
