• Dyld的原理


    dynamic load: 动态加载.它主要是用的实现库之间的动态链接,库不用被直接编译到可以执行文件中,而是在执行的时候才会去link,达到动态加载的效果.共享动态库就是利用这个原理进行的。

    • 如下通过otool -L 可执行文件可以看到它包含了如下信息,其中@rpath/xxx/usr/lib/就标示它的动态链接路径. shell xxx@xxx wwdcc % otool -L App
      App:
      @rpath/App.framework/App (compatibility version 0.0.0, current version 0.0.0)
      /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)
      ## dyld环境变量速查
    • 通过man dyld可以查看他的帮助命令
      |Command|Description|
      |---|---|
      |DYLD_FRAMEWORK_PATH|动态库加载路径的集合,系统会按照这几个文件夹路径搜索动态库,XXX.framework/Versions/A/XXX or XXX.framework/XXX,根据所安装的库名字去查找|
      |DYLD_FALLBACK_FRAMEWORK_PATH|从默认的文件路径查找 /Library/Frameworks:/System/Library/Frameworks|
      |DYLD_VERSIONED_FRAMEWORK_PATH|优先使用新版本的framework|
      |DYLD_LIBRARY_PATH|搜索dylib库的文件路径集合|
      |DYLD_FALLBACK_LIBRARY_PATH|默认dylib库,如/usr/local/lib:/usr/lib.|
      |DYLD_VERSIONED_LIBRARY_PATH|优先使用新版本的dylib|
      |DYLD_PRINT_TO_FILE|日志输出的文件路径,通常用来记录错误|
      |DYLD_SHARED_REGION|avoid不使用共享缓存,private,删除共享区域的地址空间和mmap,拷贝到私有范围的dyld共享缓存区域|
      |DYLD_INSERT_LIBRARIES|在程序加载前动态的插入新的库|
      |DYLD_FORCE_FLAT_NAMESPACE|防止其他的共享库名字冲突覆盖,强制指定当前这个库|
      |DYLD_IMAGE_SUFFIX|为动态库设置统一后缀|
      |DYLD_PRINT_OPTS|设置打印的文件描述符为2,标准错误输出|
      |DYLD_PRINT_ENV|环境变量输出|
      |DYLD_PRINT_LIBRARIES|打印加载的库|
      |DYLD_BIND_AT_LAUNCH|在启动时绑定所有应用程序需要的符号,一般建议还是使用默认的懒加载|
      |DYLD_PRINT_STATISTICS|打印动态库的主要方法的时间,分析启动时间非常有用|
      |DYLD_DISABLE_DOFSDYLD_DISABLE_DOFS|不像kernel注册静态检测|
      |DYLD_PRINT_INITIALIZERS|打印构造初始化函数, C++ statically allocated objects, 标记为 attribute((constructor))的函数, and -init functions.|
      |DYLD_PRINT_APIS|打印 dyld api的调用|
      |DYLD_PRINT_SEGMENTS|打印dyld 加载时所map的mach-o segment|
      |DYLD_PRINT_BINDINGS|打印binding的符号信息|
      |DYLD_PRINT_DOFS|使dyld打印出关于已向内核注册的dtrace静态探测的信息。|
      |DYLD_PRINT_RPATHS|打印@rpath路径|
      |DYLD_SHARED_CACHE_DIR|打印共享文件路径,通常与DYLD_SHARED_REGION=private and DYLD_SHARED_CACHE_DONT_VALIDATE 结合使用|
      |DYLD_SHARED_CACHE_DONT_VALIDATE|不关系在不在,直接去加载它|
      | DYNAMIC LIBRARY LOADING|设置动态库加载路径,drawin使用完整路径加载,通过
      @executable_path/,@loader_path/,@rpath/来指定它的库文件加载前缀|

    • 关于DYNAMIC LIBRARY LOADINGXcode中会经常遇到

      • @executable_path: 这个变量表示可执行程序所在的目录,总是被解析为同一个路径(可执行程序所在目录)
      • @loader_path: 这个变量表示每一个被加载的 binary (包括可执行程序, dylib, framework 等) 所在的目录. 它INSTALL_PATH 可以设置为 @loader_path/../dylib, 这样设置的话, 不论这个库放到什么位置它都能正确加载
      • @rpath: 它只是一个保存着一个或多个路径的变量,增加查找的路径

    App启动时间统计

    • 就App而言主要分为三种加载形式
      • 冷启动(Coding launch): App在第一次安装启动
      • 热启动(Warming launch): App关闭后立即启动(有共享缓存,暂时没销毁)
      • 正常启动: App相关的部分共享缓存释放
    • 在Xcode中通过设置环境变量DYLD_PRINT_STATISTICS_DETAILS=1可以看到dylib在linker的过程中所有关键阶段的时间d text total time: 4.0 seconds (100.0%)
      total images loaded: 691 (636 from dyld shared cache)
      total segments mapped: 178, into 23263 pages
      total images loading time: 3.0 seconds (74.5%)
      total load time in ObjC: 39.29 milliseconds (0.9%)
      total debugger pause time: 1.5 seconds (37.7%)
      total dtrace DOF registration time: 0.00 milliseconds (0.0%)
      total rebase fixups: 502,572
      total rebase fixups time: 70.65 milliseconds (1.7%)
      total binding fixups: 45,451
      total binding fixups time: 56.66 milliseconds (1.3%)
      total weak binding fixups time: 33.12 milliseconds (0.8%)
      total redo shared cached bindings time: 30.67 milliseconds (0.7%)
      total bindings lazily fixed up: 0 of 0
      total time in initializers and ObjC +load: 835.45 milliseconds (20.5%)
      libSystem.B.dylib : 9.45 milliseconds (0.2%)
      libBacktraceRecording.dylib : 6.27 milliseconds (0.1%)
      libMainThreadChecker.dylib : 39.86 milliseconds (0.9%)
      libglInterpose.dylib : 508.29 milliseconds (12.5%)
      libMTLCapture.dylib : 20.72 milliseconds (0.5%)
      RxSwift : 6.73 milliseconds (0.1%)
      RxCocoa : 8.46 milliseconds (0.2%)
      Flutter : 5.00 milliseconds (0.1%)
      Realm : 11.78 milliseconds (0.2%)
      SwiftProtobuf : 4.72 milliseconds (0.1%)
      xx_plugin : 9.50 milliseconds (0.2%)
      xxx3d : 12.38 milliseconds (0.3%)
      xxxApp : 313.05 milliseconds (7.6%)
      total symbol trie searches: 269548
      total symbol table binary searches: 0
      total images defining weak symbols: 71
      total images using weak symbols: 162

    dyld主要功能

    • docs->dyld.codes包括了dyld的主要功能大纲 codes 0x1f070000 dyld.static_intializer
      0x1f070004 dyld.launch_executable
      0x1f070008 dyld.map_file
      0x1f07000c dyld.apply_fixups
      0x1f070010 dyld.attach_codesignature
      0x1f070014 dyld.build_closure
      0x1f070018 dyld.add_image_callback
      0x1f07001c dyld.remove_image_callback
      0x1f070020 dyld.objc_image_init
      0x1f070024 dyld.objc_images_map
      0x1f070028 dyld.apply_interposing
      0x1f07002c dyld.gdb_image_notifier
      0x1f070030 dyld.remote_image_notifier
      0x1f080000 dyld.dlopen
      0x1f080004 dyld.dlopen_preflight
      0x1f080008 dyld.dlclose
      0x1f08000c dyld.dlsym
      0x1f080010 dyld.dladdr
      0x1f090000 dyld.DEBUG.vm_remap
      0x1f090004 dyld.DEBUG.vm_dealloc
      0x1f090008 dyld.DEBUG.map_loop
      0x1f09000c dyld.DEBUG.marker
      ## dyld执行过程,以arm64为例
    • kernel内核做好相关的初始化工作之后,从汇编文件dyldStartup.s -> __dyld_start `` #if arm64 ...
      __dyld_start: ...
      // call dyldbootstrap::start(app_mh, argc, argv, dyld_mh, &startGlue)
      // LC_MAIN case, set up stack for call to main() ...
      b.ne Lapple // main param4 = apple
      ...

    endif // arm64

    2. dyldInitialization.cpp -> dyldbootstrap::start 
        -> rebaseDyld, 修改二进制位置,安全策略考虑 
           -> runDyldInitializers //初始化C++的函数,
                extern const Initializer  inits_start  __asm("section$start$__DATA$__mod_init_func");
    extern const Initializer  inits_end    __asm("section$end$__DATA$__mod_init_func");
             -> dyld::_main
    1. dyld2.cpp
        -> _main
    ## TODO:
    
  • 相关阅读:
    JS数字指定长度不足前补零的实现
    IIS7设置将域名不带www跳转到带www上
    NET Core Mvc发布带视图文件的方法!
    NET Core 部署到 Windows服务
    Java配置----JDK开发环境搭建及环境变量配置
    Windows上MyEclipse2017 CI7 安装、破解以及配置
    C# 通过http post 请求上传图片和参数
    MongoDB中的数据导出为excel CSV 文件
    JS计算两个日期之间的天数,时间差计算
    IIS8.5 的环境下添加配置WCF服务!!!!!
  • 原文地址:https://www.cnblogs.com/wwoo/p/dyld-jian-jie.html
Copyright © 2020-2023  润新知