Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

初始化和终止代码的限制和缺点

ELF 初始化节和例程以及终止节和例程在目标文件生命周期的某个敏感时间执行。初始化过程中,目标文件已装入到内存中,但未完全初始化。终结化过程中,目标文件仍装入内存中,但不再能够安全使用,并且部分可能会从进程状态下删除。在任一上下文中,进程状态都不是完全一致的,而且在可以安全执行的代码方面有很大的限制。常见的缺点包括但不限于以下各项:

  • 循环依赖项导致死锁,其中,一个目标文件的初始化代码触发另一个目标文件的装入操作,反过来又回调到初始目标文件。

  • 当某共享目标文件用于多线程应用程序时,线程序列化将失败。两个线程会同时尝试访问延迟装入的库。最先成功访问的线程将导致运行时链接程序装入目标文件并开始运行初始化代码。程序员经常会误以为在 ELF 初始化代码和终止代码运行时,运行时链接程序可以防止一个以上的线程访问给定目标文件,但事实上并非如此。当初始化代码正在运行时,运行时链接程序并不能防止其他线程尝试访问库。因此可能会有第二个线程在不一致的状态下访问目标文件。目标文件的责任是提供必要的锁定或要求调用方提供必要锁定来对此类访问进行序列化。

ELF 初始化节和例程以及终止节和例程允许执行任意代码,这给人以一种错觉,即它们能够执行在正常上下文中代码可以执行的任何操作。在这种观念下,此类代码看起来不外是一种无需显式函数调用便可执行初始化或清除的便利方法。这种误解会导致难以诊断的故障。

程序员在使用 ELF 初始化代码和终止代码时应格外注意,并限制操作的范围和复杂性。链接编辑器和运行时链接程序并不了解此类代码的内容或目的,无法诊断或阻止不安全的代码。自包含的小操作是安全的。要访问其他目标文件或进程状态的操作则可能不安全。库应提供显式初始化函数和终止函数供调用方运行,并记录执行此类操作的要求,而不是尝试在初始化代码和终止代码中执行复杂的操作。

以下各节详细说明了这些问题。