Macos14.0 调试苹果开源库objc
开源库下载
1、下载地址:https://opensource.apple.com/releases/
2、根据Mac版本选择相应的库
(图1)获取Mac系统版本
(图2)找到可下载的开源库列表
3、需要下载的库列表(这里拿macos14.0为例)
需下载列表 |
dyld-1122.1 |
Libc-1583.0.14 Libc-825.26 |
libclosure-90 |
libplatform-306.0.1 |
libpthread-519 |
objc4-906 |
xnu-10002.1.13 |
准备
1、解压objc,并打开objc.xcodeproj
2、创建target用于运行objc库,Xcode->File->New->Target
3、创建Command Line Tool类型的Target(也可以选择app类型),并命名为UseObjc(名称随意)
4、选中UseObjc target
5、添加库依赖libobjc.A.dylib
6、添加Target依赖,用于编译objc.A.dylib库,UseObjc不会主动编译objc.A.dylib库
7、关闭Harden Runtime,UseObjc->Build Settings->Enable Hardened Runtime 设置为NO
8、修改objc的target,修改Run Script(markgc),macosx.internal 修改为 macosx
9、修改objc/objc-env/objc-trampolines的target,base sdk和supported platforms都修改为macOS
处理头文件缺失
此时build UseObjc的Target,发现会报头文件找不到的问题,这时候需要我们从”开源库下载“中下载到的所有库中,寻找到所需头文件,举例如下
1、build objc target时找不到sys/reason.h
2、刚刚的下载的开源库中有此reason.h
3、为了快速找到reason.h,直接在此文件夹下”按名称“搜索reason.h
4、搜索到后,我们并没办法直接使用,因为objc target依赖的是sys/reason.h,而不是reason.h
4.1、为此在objc工程下新增Common(名称随意)文件夹
4.2、并在objc target的Header search path下添加Common文件夹,让程序可以寻址到Common文件夹
4.3、Common文件夹下创建sys目录,并将搜索到的reason.h文件拷贝到sys目录下,这样子才能按照sys/reason.h寻址
5、至此,重新运行UseObjc target,找不到sys/reason.h的问题已修复,但是还有其他头文件找不到的问题
整理Macos14.0需要的头文件
头文件 | 所属位置 |
_simple.h | libplatform-libplatform-306.0.1/private/_simple.h |
Block_private.h | libclosure-libclosure-90/Block_private.h |
CrashReporterClient.h | Libc-Libc-825.26/include/CrashReporterClient.h |
objc-shared-cache.h | dyld-dyld-1122.1/include/objc-shared-cache.h |
kern/restartable.h | xnu-xnu-10002.1.13/osfmk/kern/restartable.h |
mach-o/dyld_priv.h | dyld-dyld-1122.1/include/mach-o/dyld_priv.h |
machine/cpu_capabilities.h | xnu-xnu-10002.1.13/osfmk/machine/cpu_capabilities.h |
os/api.h | Libc-Libc-1583.0.14/os/api.h |
os/base_private.h | xnu-xnu-10002.1.13/libkern/os/base_private.h |
os/bsd.h | Libc-Libc-1583.0.14/libdarwin/h/bsd.h |
os/linker_set.h | Libc-Libc-1583.0.14/os/linker_set.h |
os/lock_private.h | private/os/lock_private.h |
os/log_simple_private_impl.h | libplatform-libplatform-306.0.1/private/os/log_simple_private_impl.h |
os/log_simple_private.h | libplatform-libplatform-306.0.1/private/os/log_simple_private.h |
os/reason_private.h | xnu-xnu-10002.1.13/libkern/os/reason_private.h |
os/tsd.h | xnu-xnu-10002.1.13/libsyscall/os/tsd.h |
os/variant_private.h | Libc-Libc-1583.0.14/os/variant_private.h |
pthread/tsd_private.h | libpthread-libpthread-519/private/pthread/tsd_private.h |
sys/reason.h | xnu-xnu-10002.1.13/bsd/sys/reason.h |
System/machine/cpu_capabilities.h | xnu-xnu-10002.1.13/osfmk/cpu_capabilities.h |
System/pthread_machdep.h | Libc-Libc-825.26/pthreads/pthread_machdep.h |
其他头文件依赖 | 直接注释即可 |
如果懒得操作可直接下载我整理好的头文件:https://onebox.huawei.com/p/8191d42c36fad36c46a2d91d9e343697
处理异常
1、删除lCrashReporterClient和loah库的依赖,objc->Build Settings->other linker flags->删除这两个库
1、有些系统函数我们找不到,需要注释掉此处逻辑,
处理规则:
规则一:如果是if中的一个条件,直接删除,如果是唯一条件,则整个if语句都要注释掉,包括后面的else if/else
规则二:是函数调用中的参数,则整个函数调用都要注释掉
规则三:函数调用为”|“的一个参数,直接删除,如果是唯一参数,则注释整个逻辑
相关处理过程截图:
调试
UseObjc target的main函数中添加NSObject *obj = [NSObject alloc];看一下内存申请过程的逻辑,从下图可以看出alloc方法调用时,进入到了objc_alloc的c方法里面,这个很奇怪,为什么会发生这种事
按照常规逻辑应该有个+(id)alloc的类方法来承接,为什么会这样呢
从下图可以看出,在加载库时,会对部分方法进行重新设置实现,alloc和allocWithZone:都被替换为了objc_alloc和objc_allocWithZone的C方法
更多
更多的逻辑等待大家去探索
new的实现原理/内存分配的方式等
- 点赞
- 收藏
- 关注作者
评论(0)