共享库和延迟加载

缺省情况下,模块被装入时,系统装入程序同时自动装入所有模块的从属。 因为当链接模块时,在模块的装入程序部分保存模块的从属模块列表,所以发生了从属的装入。

模块 描述
dump-H 允许查看从属模块列表的命令。
-blazy AIX® 4.2.1及更高版本中,链接器选项用于链接模块,以便在首次使用模块中的函数时,只加载模块的部分依赖项。

使用延迟加载时,如果模块的大多数从属从未被真正使用过,就可以程序的性能。 另一方面,每个延迟加载模块的函数调用有大约 7 个指令的额外开销,且对函数的第一个调用需要装入定义模块并修改函数调用。 因此,如果在大多数从属中运行模块调用,可能不太适合使用延迟加载。

当第一次调用延迟加载模块中定义的函数时,将进行装入定义模块并查找所期望的函数的尝试。 如果找不到该模块或该函数未由该模块导出,那么缺省行为是将错误消息打印到标准错误,并以返回码 1 退出。 应用程序可以调用_lazySetErrorHandler函数并提供错误处理程序的地址,从而提供自己的错误处理程序。 调用错误处理程序需要 3 个参数:模块的名称、符号的名称,和表示错误原因的错误值。 如果错误处理程序返回,其返回值应该为所期望的函数的替代函数的地址。 如果不存在错误处理程序,_lazySetErrorHandler 的返回值为 NULL,如果存在则为上一个处理程序的地址。

使用延迟加载通常不更改程序的行为,但有一些例外。 首先,任何与模块的装入顺序有关的程序将受到影响,因为模块可能以不同的顺序被装入,而某些模块可能根本没有被装入。

其次,比较函数指针的程序在使用延迟加载时可能无法正确工作,因为单个函数可能有多个地址。 特别是如果模块 A 调用模块 B 中的函数“f”,且在链接模块 A 时指定了模块 B 的延迟加载,那么模块 A 中所计算的“f”的地址与其他模块中所计算的“f”的地址不同。 因此,在使用延迟加载时,即使两个函数指针指向同一函数,它们也可能不相等。

第三,如果用相对路径名装入了任何模块且程序更改了工作目录,那么当需要装入从属模块时可能无法找到它们。 使用延迟加载时,如要在链接时间引用从属模块,只应该使用绝对路径名。

在链接时间,启用延迟加载的决定是一个个模块作出的。 在单个程序中,可以混合将使用延迟加载和不使用延迟加载的模块混合起来。 链接单个模块时,对从属模块中的变量的引用会防止该模块被延迟加载。 如果对模块的所有引用均为对函数符号的引用,那么从属模块可被延迟加载。

延迟加载工具可被用在线程和非线程应用程序中。

延迟加载执行跟踪

提供了一个允许在发生时查看装入活动的运行时功能部件。 这是通过使用环境变量 LDLAZYDEBUG 来实现的。 该变量的值是一个十进制、八进制(以 0 开头)或十六进制(以 0x 开头)的数,它是一个或多个以下值的总和。

变量 描述
第 1 年 显示装入或查找错误。

如果没有找到所需的模块,那么显示消息并调用延迟加载的错误处理程序。 如果所需的符号在所装入的引用模块中不可用,那么在调用错误处理程序前显示消息。

2 将跟踪消息写到 stderr 而不是 stdout

缺省情况下,这些消息被写到标准输出文件流中。 该值选择了标准错误流。

4 显示正在被装入的模块的名称。

当需要新的模块来解析函数调用时,显示所发现并装入的模块名称。 这只在第一次引用模块内的函数时出现;即一旦模块被装入,它就一直可用于随后对该模块内的函数的引用。 不需要额外的装入操作。

8 周 显示所调用函数的名称。

显示所需函数功能的名称,以及预期的函数所在的模块名称。 该信息在模块被装入之前显示。