前言

为什么会想要调试源码?

苹果开源了部分源码, 但相似内容太多, 基本找不到代码见的对应关系, 如果能像自己工程一样进行跳转那多好哇~~

苹果源码开源地址: https://opensource.apple.com/

本文将以macOS 11.2/objc4-818.2的源码进行配置



源码配置

首先选中运行target: objc > My Mac

然后⌘+b进行编译

翻一下爆红的点看看都有哪些错误, 然后找到下面对应的解决方案~

编译报错 'sys/reason.h' file not found

解决方案: 谷歌中输入reason.h site:opensource.apple.com定向检索

点进去搜索结果里面, 进行"文件另存为"下载

下载后, 在objc源码根目录中创建一个文件夹"ZKLib",

然后因为reason.h文件是在sys目录下的, 所以我们在"ZKLib"目录下创建"sys"文件夹, 并把reason.h放到该目录里面(如下图)

接下来我们在源码工程 target > objc > Build Settings中搜索"Header Search Paths", 给Debug和Release都加上$(SRCROOT)/ZKLib即可

(不需要把ZKLib拉进源码Xcode工程里哦! )\

然后继续⌘+b编译



其它文件缺失

我们会发现相同的报错还有\

'mach-o/dyld_priv.h' file not found
'os/lock_private.h' file not found
'os/base_private.h' file not found
'pthread/tsd_private.h' file not found
'System/machine/cpu_capabilities.h' file not found
'os/tsd.h' file not found
'pthread/spinlock_private.h' file not found
'System/pthread_machdep.h' file not found
'CrashReporterClient.h' file not found
'objc-shared-cache.h' file not found
'_simple.h' file not found
'Block_private.h' file not found

这些报错的解决方案都跟上面的一样处理



objc源码文件代码修改

CrashReporterClient明明放进去了还是"file not found"

打开CrashReporterClient.h文件,

在#ifdef前面加上以下代码:

#define LIBC_NO_LIBCRASHREPORTERCLIENT

注释掉一些妨碍编译的代码

总的来说一共有这么多:

具体都有:

objc-cache.mm

87行:

#if TARGET_OS_OSX

//#include <Cambria/Traps.h>

//#include <Cambria/Cambria.h>

#endif

1120行:

//#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

NSObject.mm

42行:

//#include <os/feature_private.h>

extern "C" {

//#include <os/reason_private.h>

//#include <os/variant_private.h>

}

1185行:

// if (DebugPoolAllocation || sdkIsAtLeast(10_12, 10_0, 10_0, 3_0, 2_0)) {

// // OBJC_DEBUG_POOL_ALLOCATION or new SDK. Bad pop is fatal.

// _objc_fatal

// ("Invalid or prematurely-freed autorelease pool %p.", token);

// }

objc-runtime.mm

36行:

//#include <os/feature_private.h> // os_feature_enabled_simple()

379行:

// if (!dyld_program_sdk_at_least(dyld_fall_2020_os_versions))

// DisableAutoreleaseCoalescingLRU = true;

444行:

// if (!os_feature_enabled_simple(objc4, preoptimizedCaches, true)) {

// DisablePreoptCaches = true;

// }

objc-class.mm

896行:

// LINKER_SET_FOREACH(_dupi, const objc_duplicate_class **, "__objc_dupclass") {

// const objc_duplicate_class *dupi = *_dupi;

//

// if (strcmp(dupi->name, name) == 0) {

// return;

// }

// }

objc-os.mm

31行:

//#include "objc-bp-assist.h"

\

567行:

// 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-runtime-new.mm

3547行:

// 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.");

// }

// }

8328行:

if (!DisableTaggedPointerObfuscation /**&& dyld_program_sdk_at_least(dyld_fall_2018_os_versions)*/) {

编译报错 Can't open order file: libobjc.order

具体来说是这么一个报错:

解决方案:

在源码工程 target > objc > Build Settings中搜索"Order File", 把Debug和Release的内容都改成$(SRCROOT)/libobjc.order即可

编译报错 Library not found for -lCrashReporterClient

在源码工程 target > objc > Build Settings中搜索"Other Linker Flags", 把Debug和Release中的-lCrashReporterClient都删掉

编译报错 SDK "macosx.internal" cannot be located.

具体来说是这么一个报错:

解决方案:

在源码工程 target > objc > Build Phases中找到Run Script(markgc)里面, 把脚本中的macosx.internal改成macosx即可

编译报错 library not found for -loah

具体来说是这么一个报错:

解决方案:

在源码工程 target > objc > Build Settings中搜索"Other Linker Flags", 把Debug和Release里的-loah删掉

编译报错 '_static_assert' declared as an array with a negative size

具体来说是这么一个报错:

解决方案:

把报错的这两行注释掉~~



编译成功!

诶嘿嘿~

是不是突然间看到"Build Successed"就很兴奋了, 反正我是兴奋了





编译调试

新建一个target

选择macOS里面的Command Line Tool (我们这里不需要界面)

将target命名为ZKBuild (如下图)

绑定依赖关系

在源码工程 target > ZKBuild > Build Phases中

在Dependencies 添加objc

打断点进行调试

切换运行target: ZKBuild > My Mac

在main.m代码中打断点, 并按⌘+r运行

此时按

(step into)进入这一行代码里面

来到objc源码里面, 则表示已经能成功调试objc源码

使用objc4V818.2源码编译,没有什么比苹果底层源码更有说服力去证明底层原理真假的更多相关文章

  1. SSH/SSL 源码编译安装简易操作说明

    环境:CentOS 6.7 安全加固需求,由于某盟扫描系统主机有SSL系列漏洞,客户要求必须修复: 解决方案:将SSH/SSL升级到最新版本,删除SSL旧版本(实测不删除旧版本某盟扫描无法通过). 当 ...

  2. centos7源码编译安装Subversion 1.9.5

    svn是Subversion的简称,是一个开放源代码的版本控制系统.svn有两种运行方式:1.独立服务器(svn://xxx.xxx/xxx) 2.借助apache(http://svn.xxx.xx ...

  3. 【运维技术】Nginx安装教程(yum安装,源码编译)

    安装方式 yum直接更新源安装 源码直接编译之后安装 使用yum进行直接安装 Installing a Prebuilt CentOS/RHEL Package from an OS Reposito ...

  4. 日常工作之Zabbix源码编译,兼容mysql5.6

    原文链接:http://www.leleblog.top/daily/more?id=6 Zabbix源码编译 环境: centOS7.mysql5.6.21(已存在). 任务简述: 服务器搭建zab ...

  5. GDAL源码编译

    转自阿Fai, GDAL源码编译 在这里,我使用源码编译出C#可以使用的dll静态文件. 一.简单的编译 1.简单的认识 首先进入GDAL的源代码目录,可以看到有几个sln为后缀的文件名,比如make ...

  6. 十四.自定义yum仓库、源码编译安装

    pc7:192.168.4.7 1.自定义yum仓库1.1 源码仓库下:/root/tools/other]# createrepo .]# ls ntfs-3g-2014.2.15-6.el6.x8 ...

  7. CentOS7 源码编译安装Nginx

    源码编译安装nginx     1.下载nginx源码包(这里以nginx-1.18.0为例) wget http://nginx.org/download/nginx-1.18.0.tar.gz 2 ...

  8. Spring 6 源码编译和高效阅读源码技巧分享

    一. 前言 Spring Boot 3 RELEASE版本于 2022年11月24日 正式发布,相信已经有不少同学开始准备新版本的学习了,不过目前还不建议在实际项目中做升级,毕竟还有很多框架和中间件没 ...

  9. Hadoop2.x 体系结构和源码编译

    体系结构 Hadoop1的核心组成包括HDFS和MapReduce.HDFS和MapReduce的共同点就是他们都是分布式的. HDFS是包括主节点NameNode,只有一个,还有很多从节点DataN ...

  10. Android源码分析(六)-----蓝牙Bluetooth源码目录分析

    一 :Bluetooth 的设置应用 packages\apps\Settings\src\com\android\settings\bluetooth* 蓝牙设置应用及设置参数,蓝牙状态,蓝牙设备等 ...

随机推荐

  1. [转帖]Spring Cloud Alibaba Nacos 注册中心使用教程

    一. 什么是Nacos Nacos是一个更易于构建云原生应用的动态服务发现(Nacos Discovery ).服务配置(Nacos Config)和服务管理平台,集注册中心+配置中心+服务管理于一身 ...

  2. RabbitMQ 测试环境的简单创建于使用 permission vhost 以及 权限简单设置

    之前用docker运行起来 rabbitmq的容器了 但是今天发现有问题. 简单沟通了下 需要进行处理. 方法主要是如下 1. 运行容器: docker run --name rabbitmq -ti ...

  3. IPV6的简单学习与整理

    背景 大概2018年时曾经突击学习过一段时间IPV6 当时没太有写文档的习惯,导致这边没有成型的记录了. 今天又有项目要求使用IPV6, 想了想就将之前学习的部分 还有想继续学习提高的部分进行一下总结 ...

  4. 自己想的一些判断存储长度的sql

    create table zhaobsh (t1 date ,t2 TIMESTAMP) insert into zhaobsh values (CURRENT_DATE,CURRENT_TIMEST ...

  5. 《Javascript高级程序设计》读书笔记——构造函数与原型

    构造函数与原型 构造函数模式 最简单的构造函数: function Person(name, age, job) { this.name = name; this.age = age; this.jo ...

  6. 记windows自定义bat脚本自启动

    自定义 Windows 启动脚本简化版 在本指南中,我们将使用一个简化的批处理文件(.bat)来演示如何创建自定义的 Windows 启动脚本.以下是一个基本的模板,您只需根据需要在 :begin 部 ...

  7. 【JS 逆向百例】反混淆入门,某鹏教育 JS 混淆还原

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...

  8. 大数据面试题集锦-Hadoop面试题(三)-MapReduce

    你准备好面试了吗?这里有一些面试中可能会问到的问题以及相对应的答案.如果你需要更多的面试经验和面试题,关注一下"张飞的猪大数据分享"吧,公众号会不定时的分享相关的知识和资料. 目录 ...

  9. C# 使用RabbitMQ消息队列

    参考文章 https://www.cnblogs.com/kiba/p/11703073.html和https://www.cnblogs.com/longlongogo/p/6489574.html ...

  10. 9.2 Windows驱动开发:内核解析PE结构导出表

    在笔者的上一篇文章<内核特征码扫描PE代码段>中LyShark带大家通过封装好的LySharkToolsUtilKernelBase函数实现了动态获取内核模块基址,并通过ntimage.h ...