iOS底层探索0-pre 源码编译objc818.2

3,203 阅读4分钟

源码编译调试 objc4-818.2

objc4源码

准备工作:系统版本、开发工具、objc源码版本等

  • macOS Big Sur 11.5.2
  • Xcode 13.1
  • objc4-818.2

依赖文件

图片.png 图片.png

dyld
launchd
libauto
Libc
libclosure
libdispatch
libplatform
libpthread
xnu

opensource地址 opensource.apple.com/

依赖文件库的版本尽量下载最新版,找不到的文件库就从之前的版本去找
launchd-106.10 需要在Mac OS X 10.4.4下载
libauto 需要在macOS 10.15.6及以下版本下载
其他库都可以在最新的macOS 11.5 中搜索到

编译源码 及 常见问题

主要是编译 objc 这个target

图片.png

unable to find sdk 'macosx.internal'

初次编译一般会遇到
图片.png

objc 和 objc-trampolines 这两个target都会有这个问题,解决方式

  • target -> objc -> BuildSettings -> Base SDK -> macOS
  • target -> objc-trampolines -> BuildSettings -> Base SDK -> macOS

objc 和 objc-trampolines两个都要选 图片.png

'sys/reason.h' file not found

图片.png

  • reason.h 文件在 下载的文件库 xnu-7195.141.2/bsd/sys目录下

  • 在工程根目录下新建文件夹 LRCommon (名称随便取),创建子文件夹 sys ;

  • reason.h 文件拷贝到 LRCommon/sys/ 目录下 图片.png 图片.png

  • 然后设置文件搜索路径

target -> objc -> Build Settings,在工程的 Header Serach Paths 中添加搜索路径 $(SRCROOT)/LRCommon

图片.png

'mach-o/dyld_priv.h' file not found

图片.png

  • dyld_priv.h 文件在 dyld-852.2/include/mach-o 目录下
  • LRCommon目录同样创建mach-o目录拷贝文件到该目录(LRCommon/mach-o/)下

图片.png

图片.png

  • 拷贝之后还需要在 dyld_priv.h 文件添加宏定义
#define DYLD_MACOSX_VERSION_10_11 0x000A0B00
#define DYLD_MACOSX_VERSION_10_12 0x000A0C00
#define DYLD_MACOSX_VERSION_10_13 0x000A0D00
#define DYLD_MACOSX_VERSION_10_14 0x000A0E00

图片.png

  • 如果出现 bridgeos(3.0) 报错,则删除 bridgeos(3.0) 参数 图片.png

'os/lock_private.h' file not found

图片.png

找到文件位置,对应创建文件路径并拷贝文件到对应路径下

  • lock_private.h 文件在 libplatform-254.80.2/private/os 目录下
  • LRCommon目录同样创建os目录并拷贝文件到该目录下

图片.png

图片.png

'os/base_private.h' file not found

找到文件位置,对应创建文件路径并拷贝文件到对应路径下

  • os/base_private.h 文件在 libplatform-254.80.2/private/os 目录下
  • LRCommon目录同样创建os目录并拷贝文件到该目录下 这里os/base_private.h 文件在 libplatform-220.100.1版本里面才有 macOS 11中的254版本没有这个文件了,需要到 macOS 10.15及以下版本去下载,下载位置 macOS 10.15.6

图片.png

图片.png

'pthread/tsd_private.h' file not found & 'pthread/spinlock_private.h' file not found

找到文件位置,对应创建文件路径并拷贝文件到对应路径下

  • pthread/tsd_private.h 文件在 libpthread-454.120.2/private/pthread 目录下

  • LRCommon目录同样创建pthread目录并拷贝文件到该目录下

  • pthread/spinlock_private.h 文件在 libpthread-454.120.2/private/pthread 目录下

  • LRCommon目录同样创建pthread目录并拷贝文件到该目录下

'System/machine/cpu_capabilities.h' file not found

找到文件位置,对应创建文件路径并拷贝文件到对应路径下

  • pthread/cpu_capabilities.h 文件在 xnu-7195.141.2/osfmk/machine 目录下
  • LRCommon目录同样创建System/machine目录并拷贝文件到该目录下

'os/tsd.h' file not found

找到文件位置,对应创建文件路径并拷贝文件到对应路径下

  • pthread/tsd.h 文件在 xnu-7195.141.2/libsyscall/os 目录下
  • LRCommon目录同样创建os目录并拷贝文件到该目录下

'System/pthread_machdep.h' file not found

找到文件位置,对应创建文件路径并拷贝文件到对应路径下

pthread_machdep.h 文件在 Libc-583版本
下载地址 Libc-583 版本:opensource.apple.com/tarballs/Li… pthread_machdep.h 文件:opensource.apple.com/source/Libc…

  • pthread/pthread_machdep.h 文件在 Libc-583/pthreads 目录下
  • LRCommon目录同样创建System目录并拷贝文件到该目录下

'CrashReporterClient.h' file not found

CrashReporterClient.h 文件在 Libc-825.24
下载地址 Libc-825.24 版本:opensource.apple.com/tarballs/Li…

  • CrashReporterClient.h 文件在 Libc-583/pthreads 目录下
  • 直接放在LRCommon目录下

图片.png

图片.png

  • 如果导入之后还报错,则可以在 CrashReporterClient.h 文件中添加宏定义
#define LIBC_NO_LIBCRASHREPORTERCLIENT

图片.png

Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int'))

  • pthread_lock_t 重复定义了,注释掉 pthread_machdep.h 文件中的定义

图片.png

Static declaration of '_pthread_has_direct_tsd' follows non-static declaration

Static declaration of '_pthread_getspecific_direct' follows non-static declaration

都注释掉 pthread_machdep.h 文件中的定义

图片.png

'os/feature_private.h' file not found

注释掉 图片.png 图片.png

Use of undeclared identifier 'dyld_fall_2020_os_versions'

注释379-380 图片.png

'objc-bp-assist.h' file not found

注释掉该行引用

Use of undeclared identifier 'dyld_platform_version_macOS_10_13'

注释掉该段代码 图片.png

Use of undeclared identifier 'dyld_platform_version_macOS_10_11'

注释掉该段代码 图片.png

Use of undeclared identifier 'dyld_fall_2018_os_versions'

注释掉该段代码 图片.png

'objc-shared-cache.h' file not found

  • 文件路径 dyld-852.2/include
  • 拷贝到Common目录下

图片.png 图片.png

'_simple.h' file not found

  • 文件路径 libplatform-254.80.2/private
  • 拷贝到Common目录下

'os/linker_set.h' file not found

  • 文件路径 xnu-7195.141.2/bsd/sys
  • 拷贝到Common/os目录下

'Cambria/Traps.h' file not found

文件开源网站找不到 ,选择注释头文件引用

//#import <Cambria/Traps.h>
//#Import <Cambria/Cambria.h>

Use of undeclared identifier 'oah_is_current_process_translated'

Use of undeclared identifier 'objc_thread_get_rip'

并且注释掉 1121-1128行,保留1127行。 图片.png

'Block_private.h' file not found

  • 文件路径libclosure-79/Block_private.h
  • 拷贝到Common目录下

'kern/restartable.h' file not found

  • 文件路径xnu-7195.141.2/osfmk/kern
  • 拷贝到Common/kern目录下

'os/feature_private.h' file not found

直接注释引用头文件 图片.png

'os/reason_private.h' file not found

  • 文件路径 xnu-7195.141.2/libkern/os/reason_private.h
  • 拷贝到Common/os目录下

'os/variant_private.h' file not found

  • 文件路径 Libc-1439.141.1/os/variant_private.h
  • 拷贝到Common/os目录下

Use of undeclared identifier 'dyld_platform_version_bridgeOS_2_0'

图片.png 注释代码 图片.png

'_static_assert' declared as an array with a negative size

注释掉代码 图片.png

can't open order file

libobjc.order路径问题:
can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/AppleInternal/OrderFiles/libobjc.order 图片.png

  • target -> objc -> Build Settings,在工程的 Order File 中添加搜索路径 $(SRCROOT)/libobjc.order 图片.png

library not found for -lCrashReporterClient

图片.png

  • target -> objc -> Build Settings,在工程的 Other Link Flags 中删除 -lCrashReporterClient

图片.png

library not found for -loah

图片.png

  • target -> objc -> Build Settings,在工程的 Other Link Flags 中删除 -loah 图片.png

SDK "macosx.internal" cannot be located.

  • 选择 target -> objc -> Build Phases -> Run Script(markgc)
  • 把脚本文本 macosx.internal 改成 macosx

图片.png

Thread 1: hit program assert

图片.png xcode13.1 macOS Monterey 12.0.1 系统只能运行xcode13及以上版本的xcode软件了, 在该系统环境下用xcode13.1运行报这个错误, 暂时解决办法 注销掉代码
注销代码也无法解决 暂定是Monterey的问题 intel处理器的电脑 没法运行

ASSERT(sel_registerName(sel_getName(meth.name())) == meth.name());

编译源码

通过以上错误排查调整,至此源码编译通过 图片.png

  • 新建target : LRObjcBuild 图片.png
  • 绑定二进制关系 图片.png

调试源码

图片.png

断点无法断住的问题

如遇到自定义的target中 断点无法断住的问题,则把 Build Phases 中main.m文件移到最前面

  • 把 Build Phases 中main.m文件移到最前面 图片.png

  • Build Settings 中将 Enable Hardened Runtime 设置为 NO 图片.png

was compiled with optimization - stepping may behave oddly; variables may not be available.

错的的意思是;当前编译已经被Xcode 优化,

stepping may behave oddly :优化之后可能 你在 调试的时候,点击下一步或变得奇怪,比如说,点击了下一步,但是程序可能连续跳了几步

variables may not be available.:变量可能不在是变量,有时可能会发现,对象为空nil,或者对象的类型不是我们所定义的,等等各种奇怪的情况

  • 1.查看是否为为 debug 模式 图片.png

  • 2.项目的优化级别设置 图片.png

Debug 环境一般选择:None[-O0]

None[-O0]: 编译器不会优化代码,意味着更快的编译速度和更多的调试信息,默认在 Debug 模式下开启。
Fast[-O,O1]: 编译器会优化代码性能并且最小限度影响编译时间,此选项在编译时会占用更多的内存。
Faster[-O2]:编译器会开启不依赖空间/时间折衷所有优化选项。在此,编译器不会展开循环或者函数内联。此选项会增加编译时间并且提高代码执行效率。
Fastest[-O3]:编译器会开启所有的优化选项来提升代码执行效率。此模式编译器会执行函数内联使得生成的可执行文件会变得更大。一般不推荐使用此模式。
Fastest Smallest[-Os]:编译器会开启除了会明显增加包大小以外的所有优化选项。默认在 Release 模式下开启。
Fastest, Aggressive Optimization[-Ofast]:启动 -O3 中的所有优化,可能会开启一些违反语言标准的一些优化选项。一般不推荐使用此模式。
Fastest Smallest[-Os] 极小限度会影响到包大小,而且也保证了代码的执行效率,是最佳的发布选项,一般 Xcode 会在 Release 下默认选择 Fastest Smallest[-Os] 选项,较老的项目可能没有自动勾选。

  • 3.有无额外的编译c++ flag 图片.png

目前 mac OS BigSur 11.5.2 , cpu:3 GHz 四核Intel Core i5 Xcode13.1编译的objc4-818.2会遇到此类问题 ,上面的三种方法均无法解决 可以正常打印 ,暂时不管 图片.png

底层探索的方式

x/nuf<addr>

n 表示要显示的内存单元的个数


u 表示一个地址单元的长度:
b 表示单字节
h 表示双字节
w 表示四字节
g 表示八字节


f 表示显示方式,可取如下值:
x 按十六进制格式显示变量 d 按十进制格式显示变量
u 按十进制格式显示无符号整型
o 按八进制格式显示变量
t 按二进制格式显示变量
a 按十六进制格式显示变量
i 指令地址格式
c 按字符格式显示变量
f 按浮点数格式显示变量