美文网首页
应用程序加载

应用程序加载

作者: MrHardy | 来源:发表于2021-07-08 18:03 被阅读0次

    应用程序加载原理
    库:可执行的二进制文件,加载到内存
    文件类型:
    静态库 .a
    动态库 .so .dll
    两者是链接的区别

    编译过程

    我们可以直接打开工程目录Products下的.app文件找到可执行文件拖到终端可以直接运行

    加载过程

    库- 映射到内存 images

    //输出
    +[ViewController load]
    (lldb) image list
    [  0] 404C4B96-E4D1-3501-BBDA-B6895DA2626A 0x000000010080c000
    [  1] 1AC76561-4F9A-34B1-BA7C-4516CACEAED7 0x0000000101122000 /usr/lib/dyld 
    [  2] 2A92FC99-72A9-38ED-8DDD-AF4C25080124 0x0000000100820000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/dyld_sim 
    [  3] C2A18288-4AA2-3189-A1C6-5963E370DE4C 0x00007fff2071f000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework/Foundation 
    

    接下来看dyld 动态链接器


    ViewController.m bt

    dyldbootstrap jump 查找start

    //重点看返回
    return dyld::_main((macho_header*)appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue);
    

    _main jump


    getHostInfo jump


    //instantiateFromLoadedImage   镜像文件加载器
    CRSetCrashLogMessage(sLoadingCrashMessage);
            // instantiate ImageLoader for main executable
            sMainExecutable = instantiateFromLoadedImage(mainExecutableMH, mainExecutableSlide, sExecPath);
            gLinkContext.mainExecutable = sMainExecutable;
            gLinkContext.mainExecutableCodeSigned = hasCodeSignatureLoadCommand(mainExecutableMH);
    

    instantiateFromLoadedImage jump


    addImage jump


    instantiateMainExecutable jump


    allImagesCount 拿到所有镜像文件个数


    再执行runInitializers
    runInitializers jump


    //重点代码
    processInitializers(context, thisThread, timingInfo, up);
    context.notifyBatch(dyld_image_state_initialized, false);
    

    processInitializers jump


    recursiveInitialization jump


    //重点代码  
    context.notifySingle(dyld_image_state_dependents_initialized, this, &timingInfo);           
    // initialize this image        
    bool hasInitializers = this->doInitialization(context);
    

    notifySingle jump
    void (notifySingle)(dyld_image_states, const ImageLoader image, InitializerTimingList*);

    单一注册通知


    notifyMonitoringDyld
    sNotifyObjCInit

    registerObjCNotifiers jump



    sNotifyObjCInit = init;

    单个镜像文件加载->_dyld_objc_notify_register


    registerObjCNotifiers

    _os_object_init jump


    libdispatch_init jump


    发现了_os_object_init();


    libSystem_initializer jump


    //重点代码 调用libdispatch_init
        libdispatch_init();
        _libSystem_ktrace_init_func(LIBDISPATCH);
    

    doModInitFunctions jump


    //重点代码 libSystemInitialized
    if ( ! dyld::gProcessInfo->libSystemInitialized ) {
        // <rdar://problem/17973316> libSystem initializer must run first
            const char* installPath = getInstallPath();
            if ( (installPath == NULL) || (strcmp(installPath, libSystemPath(context)) != 0) )
                dyld::throwf("initializer in image (%s) that does not link with libSystem.dylib\n", this->getPath());
                }
                                
    func(context.argc, context.argv, context.envp, context.apple, &context.programVars);
    

    ImageLoaderMachO 里调用了 doModInitFunctions
    初始化镜像文件 调用doModInitFunctions


    流程梳理


    _os_object_init (libdispatch) -> _objc_init (libobjc)

    未完待续......

    相关文章

      网友评论

          本文标题:应用程序加载

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