iOS 底层原理探索之 objc4 源码debug

iOS 底层原理探索之 objc4 源码debug,第1张

前言

你是否想调试 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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/993502.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存