By default, when a module is loaded, the system loader automatically loads all of the module's dependents at the same time. This occurs because when a module is linked, a list of the module's dependent modules is saved in the loader section of the module. (You can use the dump -H command to view this information.) It is possible in AIX Versions 4.2.1 and later to link a module so that only some of its dependents are loaded when a function in the module is first used. To link a module this way, use the -blazy linker option.
When you use lazy loading, you can improve the performance of a program if most of a module's dependents are never actually used. On the other hand, every function call to a lazily loaded module has an additional overhead of about 7 instructions, and the first call to a function requires loading the defining module and modifying the function call. Therefore, if a module calls functions in most of its dependents, the appropriateness of lazy loading should be carefully considered.
Using lazy loading does not usually change the behavior of a program, but there are a few exceptions. First, any program that relies on the order that modules are loaded is going to be affected, because modules can be loaded in a different order, and some modules might not be loaded at all.
Second, a program that compares function pointers might not work correctly when lazy loading is used, because a single function can have multiple addresses. In particular, if module A calls function `f' in module B, and if lazy loading of module B was specified when module A was linked, then the address of `f' computed in module A differs from the address of `f' computed in other modules. Thus, when you use lazy loading, two function pointers might not be equal, even if they point to the same function.
Third, if any modules are loaded with relative path names and if the program changes working directories, the dependent module might not be found when it needs to be loaded. When you use lazy loading, you should use only absolute path names when referring to dependent modules at link time.
The decision to enable lazy loading is made at link time on a module-by-module basis. In a single program, you can mix modules that use lazy loading with modules that do not. When linking a single module, a reference to a variable in a dependent module prevents that module from being loaded lazily. If all references to a module are to function symbols, the dependent module can be loaded lazily.
When a function defined in a lazily loaded module is called for the first time, an attempt is made to load the defining module and find the desired function. If the module cannot be found or if the function is not exported by the module, the default behavior is to print an error message to standard error and exit with a return code of 1. An application can supply its own error handler by calling the function _lazySetErrorHandler and supplying the address of an error handler. An error handler is called with 3 arguments: the name of the module, the name of the symbol, and an error value indicating the cause of the error. If the error handler returns, its return value should be the address of a substitute function for the desired function. The return value for _lazySetErrorHandler is NULL if no error handler exists, and the address of a previous handler if one exists.
The lazy loading facility can be used in both threaded and non-threaded applications.
A runtime feature is provided that allows you to view the loading activity as it takes place. This is accomplished using the environment variable LDLAZYDEBUG. The value of this variable is a number, in decimal, octal (leading 0), or hexadecimal (leading 0x) that is the sum of one or more of the following values:
|1|| Show load or look-up errors.
If a required module cannot be found, a message displays and the lazy load error handler is called. If a requested symbol is not available in the loaded referenced module, a message displays before the error handler is called.
|2||Write tracing messages to stderr instead of stdout.|
|4|| Display the name of the module being loaded.
When a new module is required to resolve a function call, the name of the module that is found and loaded displays. This only occurs at the first reference to a function within that module; that is, once a module is loaded, it remains available for subsequent references to functions within that module. Additional load operations are not required.
|8||Display the name of the called function.|
The dump command.