你是否想调试 objc 源码,能断点跳跳跳跳进去,对 OC 底层一探究竟。于是你找到了各种官方开源源码,但是不能像我们日常 run 起来项目,进行调试。本文就手把手写清楚步骤,助你一臂之力。
注意:如果你的 macOS 系统是 12,objc4-818.2 现在不支持,需要等 Apple 更新。另,文末有已可编译的 demo。
需要准备的资源objc4-818.2
dyld-940:The Dynamic Link Editor。Apple 的动态链接器。应用被编译打包成可执行文件之后,由 dyld 链接并加载程序。贯穿 App 启动过程,包含加载依赖库、主程序。
dyld-852.2
Libc-1506.40.4
libclosure-79
libplatform-273.40.1
libpthread-485.40.4
xnu-8019.41.5:XNU 内核是 Darwin *** 作系统的一部分。用于 MacOS/iOS 系统。
pthread_machdep.h
CrashReporterClient.h
**注意:**以上资源都在不断更新
解决编译遇到的问题解压下载好的 objc4-818.2,然后打开 objc.xcodeproj。然后选择 objc 这个 target 编译一下。可以看到开始有报错。以下报错的先后次序不一定跟本文写的顺序完全一致。无非就是一些缺少引用文件,需要注释掉的代码。大家可以根据自己遇到的情况,在此文中搜索。
首先,在 objc4-818.2 工程的根目录下新建一个名为 THDependencies(文件名随意)的文件夹备用。
然后,在 Build Settings 中搜 Header Search Paths,设置下路径。
’unable to find sdk 'macosx.internal’
分别设置 objc、objc-trampolines 这两个 target 的 BuildSettings 的 Base SDK 为 macOS。
’sys/reason.h’ file not found’
将之前下载好的资源中 xun 解压,然后在 xnu/bsd/sys/ 目录下找到 reason.h 文件,copy 到 THDependencies/sys/ (THDependencies 中的 sys 为新创建,下同,缺啥补啥)
’mach-o/dyld_priv.h’ file not found
在 dyld/include/mach-o 目录下找到 dyld_priv.h,copy 到 THDependencies/mach-o/
**dyld_priv.h 文件中,error: expected ‘,’ extern dyld_platform_t dyld_get_base_platform(dyld_platform_t platform) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0)) **
删除此文件中报错方法中的 bridgeos(3.0) 参数。
’os/lock_private.h’ file not found
在 libplatform/private/os/ 找到 lock_private.h,copy 到 THDependencies/os/
lock_private.h 中 error: expected ‘,’ tvos(13.0), watchos(6.0), bridgeos(4.0)) = 0x00040000
删除 bridgeos(4.0) 这个参数。
’pthread/tsd_private.h’ file not found
在 libpthread/private/pthread/ 目录下找到 tsd_private.h,copy 到 THDependencies/pthread/
’os/base_private.h’ file not found
在 xun/libkern/os/ 找到 base_private.h,copy 到 THDependencies/os/
’System/machine/cpu_capabilities.h’ file not found
在 xnu/osfmk/machine/ 目录下找到 cpu_capabilities.h, copy 到 THDependencies/System/machine/
’os/tsd.h’ file not found
在 xnu/libsyscall/os/ 目录下找到 tsd.h, copy 到 THDependencies/os/
’pthread/spinlock_private.h’ file not found
在 libpthread/private/pthread/ 目录下找到 spinlock_private.h,copy 到 THDependencies/pthread/
’System/pthread_machdep.h’ file not found
之前准备好的资源中 pthread_machdep.h copy 到 THDependencies/System/
’pthread/spinlock_private.h’ file not found
在 libpthread/private/pthread/ 目录下找到 spinlock_private.h,copy 到 THDependencies/pthread/
’os/feature_private.h’ file not found
直接注释报错处,此头文件引用
pthread_machdep.h 中的一些报错,
如 Typedef redefinition with different types (‘int’ vs ‘volatile OSSpinLock’ (aka ‘volatile int’))、
Static declaration of 'pthread_has_direct_tsd’ follows non-static declaration、
_Static declaration of ‘_pthread_getspecific_direct’ follows non-static declaration、
Static declaration of ‘_pthread_setspecific_direct’ follows non-static declaration
注释掉报错处的代码、方法
’CrashReporterClient.h’ file not found
之前准备好的资源中 CrashReporterClient.h copy 到 THDependencies/’objc-bp-assist.h’ file not found
直接注释报错处,此头文件引用
Use of undeclared identifier 'dyld_platform_version_macOS_10_13’
直接注释掉报错处,如下代码
if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_13)) {
DisableInitializeForkSafety = true;
if (PrintInitializing) {
_objc_inform("INITIALIZE: disabling +initialize fork "
"safety enforcement because the app is "
"too old.)");
}
}
’objc-shared-cache.h’ file not found
在 dyld/include/ 目录下找到 objc-shared-cache.h,copy 到 THDependencies/
objc-opt.mm 文件中报 No member named ‘objc_stringhash_offset_t’ in namespace ‘objc_opt’ 等错误
下载个旧版本的 dyld-852.2,在 dyld/include/ 目录下找到 objc-shared-cache.h,copy 到 THDependencies/ 替换 19 中的 objc-shared-cache.h 文件。
’os/linker_set.h’ file not found
在 xnu/bsd/sys/ 目录下找到 linker_set.h,copy 到 THDependencies/os/
’_simple.h’ file not found
在 libplatform/private/ 目录下找到 _simple.h,copy 到 THDependencies/
’Block_private.h’ file not found
在 libclosure/ 目录下找到 Block_private.h,copy 到 THDependencies/
’Cambria/Traps.h’ file not found
直接注释报错处对此类的引用
’kern/restartable.h’ file not found
在 xnu/osfmk/kern/ 目录下找到 restartable.h,copy 到 THDependencies/kern/
’os/feature_private.h’ file not found
直接注释报错处对此类的引用
Use of undeclared identifier 'oah_is_current_process_translated’
改为
’os/reason_private.h’ file not found
在 xnu/libkern/os/ 目录下找到 reason_private.h,copy 到 THDependencies/os/
’os/variant_private.h’ file not found
在 Libc/os/ 目录下找到 variant_private.h,copy 到 THDependencies/os/
Use of undeclared identifier 'dyld_fall_2020_os_versions’
改为
objc-runtime.mm 文件中报 Use of undeclared identifier 'objc4’
改为
Use of undeclared identifier 'dyld_platform_version_macOS_10_11’
改为
variant_private.h 文件中报 error: expected ‘,’ API_AVAILABLE(macosx(10.16), ios(14.0), tvos(13.0), watchos(7.0), bridgeos(4.0)) 等
删除报错处 bridgeos 参数
’_static_assert’ declared as an array with a negative size
注释掉报错处的代码
//STATIC_ASSERT((~ISA_MASK & MACH_VM_MAX_ADDRESS) == 0 ||
// ISA_MASK + sizeof(void*) == MACH_VM_MAX_ADDRESS);
Use of undeclared identifier 'dyld_platform_version_macOS_10_12’
注释掉报错处的 if 判断
Use of undeclared identifier 'dyld_fall_2018_os_versions’
在 objc-runtime-new.mm 文件的报错处,注释掉 initializeTaggedPointerObfuscator 方法内的实现。
Can’t open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/AppleInternal/OrderFiles/libobjc.order
在 objc 这个 target 的 Build Settings 中,搜索 Order File,然后在其中添加搜索路径 $(SRCROOT)/libobjc.order
Library not found for -lCrashReporterClient
在 objc 这个 target 的 Build Settings 中,搜索 Other Linker Flags,然后在其中删除 -lCrashReporterClient
Library not found for -loah
在 objc 这个 target 的 Build Settings 中,搜索 Other Linker Flags,然后在其中删除 -loah
error: SDK “macosx.internal” cannot be located.
调试举例新建一个 target。如 THObjcDebugDemo
添加依赖。
然后就可以自由发挥了。
注意:此时你在底层源码中打断点,会发觉断点无效。需要在 **Build Settings **中将 Enable Hardened Runtime 设为 NO。
Objc4Debug欢迎分享,转载请注明来源:内存溢出
评论列表(0条)