Environment Variables

Xcode 中从 Project -> Scheme -> Edit Scheme 选择,在 Arguments 下可以添加运行时的环境变量:

添加环境变量是调试利器,可以帮助我们提高调试效率,分析排查一些问题。比如调试调试僵尸对象(已经释放的对象引起的 Crash)时使用的 NSZombieEnabled 环境变量,以及调试 CGContext 创建及绘制时使用的 CGBITMAP_CONTEXT_LOG_ERRORS 和 CG_CONTEXT_SHOW_BACKTRACE 变量,以及分析启动时长使用的DYLD_PRINT_STATISTICS变量等。

那么问题来了,一些常用的环境变量有哪些,具体又是什么作用呢?

输入如下命令行
$ export OBJC_HELP=1
$ /Applications/Safari.app/Contents/MacOS/Safari 

得到OBJC相关的环境变量列表

objc[9546]: Objective-C runtime debugging. Set variable=YES to enable.
objc[9546]: OBJC_HELP: describe available environment variables
objc[9546]: OBJC_PRINT_OPTIONS: list which options are set
objc[9546]: OBJC_PRINT_IMAGES: log image and library names as they are loaded
objc[9546]: OBJC_PRINT_IMAGE_TIMES: measure duration of image loading steps
objc[9546]: OBJC_PRINT_LOAD_METHODS: log calls to class and category +load methods
objc[9546]: OBJC_PRINT_INITIALIZE_METHODS: log calls to class +initialize methods
objc[9546]: OBJC_PRINT_RESOLVED_METHODS: log methods created by +resolveClassMethod: and +resolveInstanceMethod:
objc[9546]: OBJC_PRINT_CLASS_SETUP: log progress of class and category setup
objc[9546]: OBJC_PRINT_PROTOCOL_SETUP: log progress of protocol setup
objc[9546]: OBJC_PRINT_IVAR_SETUP: log processing of non-fragile ivars
objc[9546]: OBJC_PRINT_VTABLE_SETUP: log processing of class vtables
objc[9546]: OBJC_PRINT_VTABLE_IMAGES: print vtable images showing overridden methods
objc[9546]: OBJC_PRINT_CACHE_SETUP: log processing of method caches
objc[9546]: OBJC_PRINT_FUTURE_CLASSES: log use of future classes for toll-free bridging
objc[9546]: OBJC_PRINT_PREOPTIMIZATION: log preoptimization courtesy of dyld shared cache
objc[9546]: OBJC_PRINT_CXX_CTORS: log calls to C++ ctors and dtors for instance variables
objc[9546]: OBJC_PRINT_EXCEPTIONS: log exception handling
objc[9546]: OBJC_PRINT_EXCEPTION_THROW: log backtrace of every objc_exception_throw()
objc[9546]: OBJC_PRINT_ALT_HANDLERS: log processing of exception alt handlers
objc[9546]: OBJC_PRINT_REPLACED_METHODS: log methods replaced by category implementations
objc[9546]: OBJC_PRINT_DEPRECATION_WARNINGS: warn about calls to deprecated runtime functions
objc[9546]: OBJC_PRINT_POOL_HIGHWATER: log high-water marks for autorelease pools
objc[9546]: OBJC_PRINT_CUSTOM_RR: log classes with un-optimized custom retain/release methods
objc[9546]: OBJC_PRINT_CUSTOM_AWZ: log classes with un-optimized custom allocWithZone methods
objc[9546]: OBJC_PRINT_RAW_ISA: log classes that require raw pointer isa fields
objc[9546]: OBJC_DEBUG_UNLOAD: warn about poorly-behaving bundles when unloaded
objc[9546]: OBJC_DEBUG_FRAGILE_SUPERCLASSES: warn about subclasses that may have been broken by subsequent changes to superclasses
objc[9546]: OBJC_DEBUG_NIL_SYNC: warn about @synchronized(nil), which does no synchronization
objc[9546]: OBJC_DEBUG_NONFRAGILE_IVARS: capriciously rearrange non-fragile ivars
objc[9546]: OBJC_DEBUG_ALT_HANDLERS: record more info about bad alt handler use
objc[9546]: OBJC_DEBUG_MISSING_POOLS: warn about autorelease with no pool in place, which may be a leak
objc[9546]: OBJC_DEBUG_POOL_ALLOCATION: halt when autorelease pools are popped out of order, and allow heap debuggers to track autorelease pools
objc[9546]: OBJC_DEBUG_DUPLICATE_CLASSES: halt when multiple classes with the same name are present
objc[9546]: OBJC_DEBUG_DONT_CRASH: halt the process by exiting instead of crashing
objc[9546]: OBJC_DISABLE_VTABLES: disable vtable dispatch
objc[9546]: OBJC_DISABLE_PREOPTIMIZATION: disable preoptimization courtesy of dyld shared cache
objc[9546]: OBJC_DISABLE_TAGGED_POINTERS: disable tagged pointer optimization of NSNumber et al.
objc[9546]: OBJC_DISABLE_NONPOINTER_ISA: disable non-pointer isa fields
objc[9546]: OBJC_DISABLE_INITIALIZE_FORK_SAFETY: disable safety checks for +initialize after fork
2019-05-29 09:53:28.903 Safari[9546:4479239] .sdef warning for argument 'FileType' of command 'save' in suite 'Standard Suite': 'saveable file format' is not a valid type name.

那么dyld变量又有哪些呢?可以使用两种方案获取,一种是直接通过命令行获取,如下:

输入如下命令行
$ man dyld

得到了dyld变量列表

DYLD(1)       
                                                                                                                                             
NAME
       dyld - the dynamic linker

SYNOPSIS
       DYLD_FRAMEWORK_PATH
       DYLD_FALLBACK_FRAMEWORK_PATH
       DYLD_VERSIONED_FRAMEWORK_PATH
       DYLD_LIBRARY_PATH
       DYLD_FALLBACK_LIBRARY_PATH
       DYLD_VERSIONED_LIBRARY_PATH
       DYLD_PRINT_TO_FILE
       DYLD_SHARED_REGION
       DYLD_INSERT_LIBRARIES
       DYLD_FORCE_FLAT_NAMESPACE
       DYLD_IMAGE_SUFFIX
       DYLD_PRINT_OPTS
       DYLD_PRINT_ENV
       DYLD_PRINT_LIBRARIES
       DYLD_BIND_AT_LAUNCH
       DYLD_DISABLE_DOFS
       DYLD_PRINT_APIS
       DYLD_PRINT_BINDINGS
       DYLD_PRINT_INITIALIZERS
       DYLD_PRINT_REBASINGS
       DYLD_PRINT_SEGMENTS
       DYLD_PRINT_STATISTICS
       DYLD_PRINT_DOFS
       DYLD_PRINT_RPATHS
       DYLD_SHARED_CACHE_DIR
       DYLD_SHARED_CACHE_DONT_VALIDATE

第二种直接通过dyld源码获得。

// 
// state of all environment variables dyld uses
//
struct EnvironmentVariables {
    const char* const *         DYLD_FRAMEWORK_PATH;
    const char* const *         DYLD_FALLBACK_FRAMEWORK_PATH;
    const char* const *         DYLD_LIBRARY_PATH;
    const char* const *         DYLD_FALLBACK_LIBRARY_PATH;
    const char* const *         DYLD_ROOT_PATH;
    const char* const *         DYLD_INSERT_LIBRARIES;
    const char* const *         LD_LIBRARY_PATH;            // for unix conformance
    bool                        DYLD_PRINT_LIBRARIES;
    bool                        DYLD_PRINT_LIBRARIES_POST_LAUNCH;
    bool                        DYLD_BIND_AT_LAUNCH;
    bool                        DYLD_PRINT_STATISTICS;
    bool                        DYLD_PRINT_OPTS;
    bool                        DYLD_PRINT_ENV;
    bool                        DYLD_DISABLE_DOFS;
                            //  DYLD_IMAGE_SUFFIX               ==> gLinkContext.imageSuffix
                            //  DYLD_PRINT_OPTS                 ==> gLinkContext.verboseOpts
                            //  DYLD_PRINT_ENV                  ==> gLinkContext.verboseEnv
                            //  DYLD_FORCE_FLAT_NAMESPACE       ==> gLinkContext.bindFlat
                            //  DYLD_PRINT_INITIALIZERS         ==> gLinkContext.verboseInit
                            //  DYLD_PRINT_SEGMENTS             ==> gLinkContext.verboseMapping
                            //  DYLD_PRINT_BINDINGS             ==> gLinkContext.verboseBind
                            //  DYLD_PRINT_REBASINGS            ==> gLinkContext.verboseRebase
                            //  DYLD_PRINT_DOFS                 ==> gLinkContext.verboseDOF
                            //  DYLD_PRINT_APIS                 ==> gLogAPIs
                            //  DYLD_IGNORE_PREBINDING          ==> gLinkContext.prebindUsage
                            //  DYLD_PREBIND_DEBUG              ==> gLinkContext.verbosePrebinding
                            //  DYLD_NEW_LOCAL_SHARED_REGIONS   ==> gLinkContext.sharedRegionMode
                            //  DYLD_SHARED_REGION              ==> gLinkContext.sharedRegionMode
                            //  DYLD_PRINT_WARNINGS             ==> gLinkContext.verboseWarnings
};

到此为止,我们得到了dyld和objc相关的环境变量列表集合。
具体各个变量是什么含义,这边就不展开了,有兴趣的可以查看https://xcoder.tips/runtime-env/,这边列举了开发过程中可能会用到的一些变量和具体作用。如果还是觉得不够详细,可以直接去官方文档查看Apple documentation - Mac OS X Debugging Magic

参考链接:

  • https://xcoder.tips/runtime-env/
  • https://blog.csdn.net/u011342466/article/details/79672219
  • https://developer.apple.com/library/archive/technotes/tn2124/_index.html

该篇故事已经结尾,下一篇文章,想谈下main之前所做的事情,dyld到底做了什么,怎么把mach-o、动态库这些东西整合起来,然后又怎么衔接到objc,这中间的流程是怎么样的?算是做个预告吧。

你可能感兴趣的:(Environment Variables)