一、当前环境
- macOS Monterey 版本:12.0.1
- Xcode Version 13.1
- objc4-818.2
二、获取源码
objc4-818.2 最新的在 macOS Big Sur -> macOS 11.2 -> objc4-818.2
可以先找到以下文件备用(这都是我照 macOS 11.2 下载的版本 其中有几个文件没有 在Libc-825.40.1中可以找到):
| 文件名 | 查找位置 |
|---|---|
| sys/reason.h | xnu-7195.81.3/bsd/sys/reason.h |
| mach-o/dyld_priv.h | dyld-832.7.3/include/mach-o/dyld_priv.h |
| os/lock_private.h | libplatform-254.80.2/private/os/lock_private.h |
| os/base_private | xnu-7195.81.3/libkern/os/base_private.h |
| pthread/tsd_private.h | libpthread-454.80.2/private/pthread/tsd_private.h |
| System/machine/cpu_capabilities.h | xnu-7195.81.3/osfmk/machine/cpu_capabilities.h |
| os/tsd.h | xnu-7195.81.3/libsyscall/os/tsd.h |
| pthread/spinlock_private.h | libpthread-454.80.2/private/pthread/spinlock_private.h |
| System/pthread_machdep.h | Libc-825.40.1/pthreads/pthread_machdep.h |
| CrashReporterClient.h | Libc-825.40.1/include/CrashReporterClient.h |
| objc-shared-cache.h | dyld-832.7.3/include/objc-shared-cache.h |
| _simple.h | libplatform-254.80.2/private/_simple.h |
| Block_private.h | libdispatch-1271.40.12/src/BlocksRuntime/Block_private.h |
| kern/restartable.h | xnu-7195.81.3/osfmk/kern/restartable.h |
| os/linker_set.h | Libc-1439.40.11/os/linker_set.h |
| os/reason_private.h | xnu-7195.81.3/libkern/os/reason_private.h |
| os/variant_private.h | Libc-1439.40.11/os/variant_private.h |
| os/feature_private.h | 注释 |
| objc-bp-assist.h | 注释 |
| Cambria/Traps.h | 注释 |
| Cambria/Cambria.h | 注释 |
三、系统超过11.2的报错信息
- 解压
objc4-818.2 - 打开工程
- 因为最新系统的
objc4还没开源 如果你和我一样的系统超过11.2配置到中间部分会报错 ⚠️错误信息Cannot combine with previous 'static' declaration specifier Expected unqualified-id
解决办法:
打开工程以后 直接将 TARGET -> objc -> Deployment Target 设置为 11.0
四、开始配置
1.scheme设置为objc
2.unable to find sdk 'macosx.internal'
- PROJECT -> objc -> Base SDK 改为macOS
- TARGETS -> objc -> Base SDK 改为macOS
3.头文件缺失
3.01'sys/reason.h' file not found
这就可以用上我们上面找的文件了
- 先创建一个文件夹名字可以随意 我这里叫
include放到跟目录下 - 将
reason.h文件放在include/sys/路径下 - 将
include添加到头文件搜索路径
3.02.mach-o/dyld_priv.h' file not found
找到头文件添加到include/mach-o/
3.03.'os/lock_private.h' file not found
找到头文件添加到include/os/
3.04.'os/base_private.h' file not found
找到头文件添加到include/os/
3.05.'pthread/tsd_private.h' file not found
找到头文件添加到include/pthread/
3.06.'System/machine/cpu_capabilities.h' file not found
找到头文件添加到include/System/machine/
3.07.'os/tsd.h' file not found
找到头文件添加到include/os/
3.08.'pthread/spinlock_private.h' file not found
找到头文件添加到include/pthread/
3.09.'System/pthread_machdep.h' file not found
找到头文件添加到include/System/
3.10.'CrashReporterClient.h' file not found
找到头文件添加到include/,然后在
TARGET -> objc -> build setting -> Preprocessor Macros 添加 LIBC_NO_LIBCRASHREPORTERCLIENT
3.11.'objc-shared-cache.h' file not found
找到头文件添加到include/
3.12.'_simple.h' file not found
找到头文件添加到include/
3.13.'Block_private.h' file not found
找到头文件添加到include/
3.14.'kern/restartable.h' file not found
找到头文件添加到include/kern
3.15.'os/linker_set.h' file not found
找到头文件添加到include/os
3.16.'os/reason_private' file not found
找到头文件添加到include/os
3.17.'os/variant_private.h' file not found
找到头文件添加到include/os
一共17个.h文件 添加后如下图
4.头文件缺失注释(4个头文件)
4.1.'os/feature_private.h' file not found
注释掉
//#include <os/feature_private.h> // os_feature_enabled_simple()
4.2.'objc-bp-assist.h' file not found
4.3.'Cambria/Traps.h' file not found
4.4.'Cambria/Cambria.h' file not found
5.API_AVAILABLE(macosx(10.16)) API_UNAVAILABLE(ios, tvos, watchos, bridgeos)
去掉最后一个参数
API_AVAILABLE(macosx(10.16)) API_UNAVAILABLE(ios, tvos, watchos)
__API_AVAILABLE参数中, bridgeos(XX)都删除
6.pthread_machdep.h文件中报错的都注释掉
//typedef int pthread_lock_t;
//
//__inline__ static int
//_pthread_has_direct_tsd(void)
//{
//#if TARGET_IPHONE_SIMULATOR
// /* Simulator will use the host implementation, so bypass the macro that is in the target code */
// return 0;
//#elif defined(__ppc__)
// int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES;
// if (*caps & kFastThreadLocalStorage) {
// return 1;
// } else {
// return 0;
// }
//#else
// return 1;
//#endif
//}
/* To be used with static constant keys only */
//__inline__ static void *
//_pthread_getspecific_direct(unsigned long slot)
//{
// void *ret;
//#if defined(__i386__) || defined(__x86_64__)
// __asm__("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *))));
//#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
// void **__pthread_tsd;
//#if defined(__arm__) && defined(_ARM_ARCH_6)
// uintptr_t __pthread_tpid;
// __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
// __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
//#elif defined(__arm__) && defined(_ARM_ARCH_5)
// register uintptr_t __pthread_tpid asm ("r9");
// __pthread_tsd = (void**)__pthread_tpid;
//#endif
// ret = __pthread_tsd[slot];
//#else
//#error no _pthread_getspecific_direct implementation for this arch
//#endif
// return ret;
//}
/* To be used with static constant keys only */
//__inline__ static int
//_pthread_setspecific_direct(unsigned long slot, void * val)
//{
//#if defined(__i386__)
//#if defined(__PIC__)
// __asm__("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
//#else
// __asm__("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val));
//#endif
//#elif defined(__x86_64__)
// /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */
// __asm__("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
//#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
// void **__pthread_tsd;
//#if defined(__arm__) && defined(_ARM_ARCH_6)
// uintptr_t __pthread_tpid;
// __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
// __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
//#elif defined(__arm__) && defined(_ARM_ARCH_5)
// register uintptr_t __pthread_tpid asm ("r9");
// __pthread_tsd = (void**)__pthread_tpid;
//#endif
// __pthread_tsd[slot] = val;
//#else
//#error no _pthread_setspecific_direct implementation for this arch
//#endif
// return 0;
//}
7.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.)");
// }
// }
8.Use of undeclared identifier 'dyld_fall_2020_os_versions'
// if (!dyld_program_sdk_at_least(dyld_fall_2020_os_versions))
// DisableAutoreleaseCoalescingLRU = true;
9.Use of undeclared identifier 'objc4' Use of undeclared identifier 'preoptimizedCaches'
// if (!os_feature_enabled_simple(objc4, preoptimizedCaches, true)) {
// DisablePreoptCaches = true;
// }
10.Mismatch in debug-ness macros
//#error mismatch in debug-ness macros
11.Use of undeclared identifier 'oah_is_current_process_translated'
//#if TARGET_OS_OSX
// if (oah_is_current_process_translated()) {
// kern_return_t ret = objc_thread_get_rip(threads[count], (uint64_t*)&pc);
// if (ret != KERN_SUCCESS) {
// pc = PC_SENTINEL;
// }
// } else {
// pc = _get_pc_for_thread (threads[count]);
// }
//#else
pc = _get_pc_for_thread (threads[count]);//留下
//#endif
12.Use of undeclared identifier 'dyld_platform_version_macOS_10_11'
// if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_11)) {
// DisableNonpointerIsa = true;
// if (PrintRawIsa) {
// _objc_inform("RAW ISA: disabling non-pointer isa because "
// "the app is too old.");
// }
// }
13.Use of undeclared identifier 'dyld_fall_2018_os_versions'
static void
initializeTaggedPointerObfuscator(void)
{ //&& dyld_program_sdk_at_least(dyld_fall_2018_os_versions)
if (!DisableTaggedPointerObfuscation) {
...
#if OBJC_SPLIT_TAGGED_POINTERS
...
#endif
} else {
...
}
}
14.Use of undeclared identifier 'dyld_platform_version_bridgeOS_2_0'
// || sdkIsAtLeast(10_12, 10_0, 10_0, 3_0, 2_0) 拿出来注释掉
if (DebugPoolAllocation) {
// OBJC_DEBUG_POOL_ALLOCATION or new SDK. Bad pop is fatal.
_objc_fatal
("Invalid or prematurely-freed autorelease pool %p.", token);
}
15.'_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);
16. can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/AppleInternal/OrderFiles/libobjc.order
TARGET -> objc -> Order File 改为 $(SRCROOT)/libobjc.order
17.library not found for -lCrashReporterClient
TARGET -> objc -> Other Linker Flags 删除 -lCrashReporterClient
18.library not found for -loah
TARGET -> objc -> Other Linker Flags 删除 -loah
19.SDK "macosx.internal" cannot be located.
TARGET -> objc -> Build Phases 中的脚本 删除.internal
20.编译成功
五、源码调试
1.创建一个终端命令行
File -> New -> Target... -> macOS -> Application -> Command Line Tool
Product name MMTest(自定义)
2.添加依赖
TARGET -> MMTest -> Dependcies -> ➕ objc(objc)
TARGET -> MMTest -> Link Binary With Libraries -> ➕ libobjc.A/dylib
3.创建文件
MMTest下创建一个继承NSObject命名为MMObject的类main函数导入MMObject并实例化一个对象- 在main中打上断点
#import <Foundation/Foundation.h>
#import "MMObject.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
MMObject *objc = [MMObject alloc];
}
return 0;
}
4.如果进不了断点
TARGET -> MMTest -> Build Phases -> Compile Sources
main.m放在最上面
5.进不去底层源码
target -> objc -> Build Settings -> Enable Hardened Runtime -> NO
6.如果是12的系统会直接崩在这里,这里我也没有很好的解决办法
ASSERT(sel_registerName(sel_getName(meth.name())) == meth.name());
7. 12以下的版本就可以进入源码调试了
然后我们就可以愉快的调试了😄