美文网首页
探究APP启动流程

探究APP启动流程

作者: Eli_app | 来源:发表于2021-07-09 20:15 被阅读0次

    从main函数探究

    我们知道main()函数是入口函数,那么我们探究APP的启动流程就先从main函数开始,我们直接断点main函数尝试一下

    image

    我们可以看到从main函数入手看不到堆栈调用,说明main函数被其他调用,而且不处于APP启动的堆栈中。

    根据经验,load()函数加载比较早,我们从load()函数入手是不是能有所收获呢

    从load()函数探究

    从load()函数下断点,开始调试

    image

    在这里可以发现很多堆栈信息_dyld_start我们准备了dyld源码,准备一探究竟

    image

    我们看到前面就是获取一些参数,然后调用dyldbootstrap::start(app_mh, argc, argv, dyld_mh, &startGlue)那么这个函数应该重要,我们跟进去看看

    image

    这个里面做一些dyld的启动引导,直接进入了dyld::_main()函数,继续跟进去看看

    image

    我们找到了这个函数,有点长,800+行,我们分块进行分析

    1、配置环境

    image

    2、加载共享缓存

    image

    3、为可执行程序实例化ImageLoader

    image

    4、加载dyld插入的库文件

    image

    5、链接插入的库文件

    image

    6、镜像文件链接之后建立弱绑定

    image

    7、运行主程序

    image

    8、我们继续跟进去看initializeMainExecutable()的实现,我们发现里面最主要的代码就是runInitializers()方法

    image

    9、在runInitializers()里面我们看到processInitializers()方法,继续跟进

    image

    10、processInitializers()里面最主要就是对镜像文件进行递归调用,我们继续跟进recursiveInitialization()

    image

    我们发现,这个里面的代码,最主要的就是notifySingle()this->doInitialization(context);,先看notifySingle()方法有没有我们想找的

    11、我们发现notifySingle()方法里面主要是设置macho的header和path等等一些信息,我们继续跟进sNotifyObjCInit()

    image

    12、我们全局搜索之后,发现在registerObjCNotifiers()方法里面被调用,那我们继续跟踪看看registerObjCNotifiers()被谁调用

    image

    13、此方法只有在一个地方被调用过就是_dyld_objc_notify_register(),这个函数太熟悉了,就是在我们在runtime里面objc_init里面的方法,一模一样,难道是巧合吗?我们找来runtime的源码继续探究

    image

    从libobjc.A.dylib库继续探究

    我们找来libobjc.A.dylib库,在void _objc_init(void)方法后面下断点,直接运行,然后打印一下当前堆栈

    image

    我们发现调用_objc_init的方法来自于libdispatch.dylib库里面的_os_object_init方法,我们证实一下流程。

    从libdispatch.dylib库证实调用流程

    1、从苹果开源库中下载libdispatch.dylib,打开工程后全局搜_os_object_init

    image

    我们发现第一行代码就是_objc_init,证实了流程。我们继续寻找libdispatch_init方法,看看是否调用了_os_object_init方法

    2、全局搜索之后,我们在倒数第三行发现了_os_object_init();方法

    image

    我们继续跟踪libdispatch_init方法的调用

    从libSystem.B.dylib库证实调用流程

    1、从苹果开源库找到libSystem.B.dylib的源码,全局搜索libSystem_initializer方法

    image

    我们在第239行的位置,找到了libdispatch_init();的调用

    总结

    整个流程分析下来,大概流程图如下所示

    image

    相关文章

      网友评论

          本文标题:探究APP启动流程

          本文链接:https://www.haomeiwen.com/subject/istqpltx.html