运行时链接程序可以针对任何在运行应用程序时处理的共享库生成配置信息。运行时链接程序负责将共享库绑定到应用程序,因此它可以拦截任何全局函数绑定。这些绑定通过 .plt 项执行。有关此机制的详细信息,请参见执行重定位的时间。
LD_PROFILE 环境变量将指定配置文件的共享库名称。可以使用此环境变量分析单个共享库。可以使用此环境变量的设置来分析一个或多个应用程序使用此共享库的方式。在以下示例中,将分析命令 ls(1) 的单次调用如何使用 libc:
$ LD_PROFILE=libc.so.1 ls -l |
在以下示例中,将在配置文件中记录此环境变量设置。此设置会使用应用程序的 libc 用法累积分析信息:
# crle -e LD_PROFILE=libc.so.1 $ ls -l $ make $ ... |
启用配置时,便会创建配置数据文件(如果尚未存在)。此文件由运行时链接程序进行映射。在上述示例中,此数据文件为 /var/tmp/libc.so.1.profile。64 位库需要扩展配置文件格式,并使用 .profilex 后缀写入。还可以指定备用目录,以便使用 LD_PROFILE_OUTPUT 环境变量存储配置数据。
此配置数据文件用于存储 profil(2) 数据,并调用与使用指定共享库相关的计数信息。使用 gprof(1) 可以直接检查此配置数据。
gprof(1) 最常用于分析由可执行文件(已使用 cc(1) 的 -xpg 选项进行编译)创建的 gmon.out 配置数据。运行时链接程序的配置文件分析不要求使用此选项编译任何代码。其相关共享库正在配置的应用程序不应该调用 profil(2),因为此系统调用不会在同一进程中提供多次调用。由于相同的原因,不能使用 cc(1) 的 -xpg 选项编译这些应用程序。这种编译器生成的配置机制也会在 profil(2) 的顶部生成。
此配置机制最强大的功能之一就是可以分析由多个应用程序使用的共享库。通常,使用一个或两个应用程序执行配置分析。但是,共享库就其本质而言可供多个应用程序使用。分析这些应用程序使用共享库的方式,可以了解应在何处投入更多精力以改善共享库的整体性能。
以下示例给出了在某个源分层结构中创建多个应用程序时对 libc 进行的性能分析。
$ LD_PROFILE=libc.so.1 ; export LD_PROFILE $ make $ gprof -b /lib/libc.so.1 /var/tmp/libc.so.1.profile ..... granularity: each sample hit covers 4 byte(s) .... called/total parents index %time self descendents called+self name index called/total children ..... ----------------------------------------------- 0.33 0.00 52/29381 _gettxt [96] 1.12 0.00 174/29381 _tzload [54] 10.50 0.00 1634/29381 <external> 16.14 0.00 2512/29381 _opendir [15] 160.65 0.00 25009/29381 _endopen [3] [2] 35.0 188.74 0.00 29381 _open [2] ----------------------------------------------- ..... granularity: each sample hit covers 4 byte(s) .... % cumulative self self total time seconds seconds calls ms/call ms/call name 35.0 188.74 188.74 29381 6.42 6.42 _open [2] 13.0 258.80 70.06 12094 5.79 5.79 _write [4] 9.9 312.32 53.52 34303 1.56 1.56 _read [6] 7.1 350.53 38.21 1177 32.46 32.46 _fork [9] .... |
特殊名称 <external> 指示要从正在配置的共享库的地址范围之外进行引用。因此,在上一示例中,从可执行文件,或者从其他共享库(正在进行配置分析时绑定到 libc)对 libc 中的 open(2) 函数进行了 1634 次调用。
共享库配置具有多线程安全性,但以下情况除外:一个线程调用 fork(2),而另一个线程正在更新配置数据信息。可以使用 fork(2) 删除此限制。