跳过导航链接 | |
退出打印视图 | |
Oracle Solaris 11.1 链接程序和库指南 Oracle Solaris 11.1 Information Library (简体中文) |
为了解缺省的符号搜索模型并将其与直接绑定进行比较,我们使用以下组件来生成一个进程。
$ cat main.c extern int W(), X(); int main() { return (W() + X()); } $ cat W.c extern int b(); int a() { return (1); } int W() { return (a() - b()); } $ cat w.c int b() { return (2); } $ cat X.c extern int b(); int a() { return (3); } int X() { return (a() - b()); } $ cat x.c int b() { return (4); } $ cc -o w.so.1 -G -Kpic w.c $ cc -o W.so.1 -G -Kpic W.c -R. w.so.1 $ cc -o x.so.1 -G -Kpic x.c $ cc -o X.so.1 -G -Kpic X.c -R. x.so.1 $ cc -o prog1 -R. main.c W.so.1 X.so.1
应用程序的组件按以下顺序装入。
$ ldd prog1 W.so.1 => ./W.so.1 X.so.1 => ./X.so.1 w.so.1 => ./w.so.1 x.so.1 => ./x.so.1
W.so.1 和 X.so.1 文件都定义了一个名为 a() 的函数。w.so.1 和 x.so.1 文件都定义了一个名为 b() 的函数。此外,W.so.1 和 X.so.1 文件都引用了函数 a() 和 b()。
通过设置 LD_DEBUG 环境变量,可以观察使用缺省搜索模型及最终绑定的运行时符号搜索。从运行时链接程序诊断信息中,可以发现到函数 a() 和 b() 的绑定。
$ LD_DEBUG=symbols,bindings prog1 ..... 17375: symbol=a; lookup in file=prog1 [ ELF ] 17375: symbol=a; lookup in file=./W.so.1 [ ELF ] 17375: binding file=./W.so.1 to file=./W.so.1: symbol `a' ..... 17375: symbol=b; lookup in file=prog1 [ ELF ] 17375: symbol=b; lookup in file=./W.so.1 [ ELF ] 17375: symbol=b; lookup in file=./X.so.1 [ ELF ] 17375: symbol=b; lookup in file=./w.so.1 [ ELF ] 17375: binding file=./W.so.1 to file=./w.so.1: symbol `b' ..... 17375: symbol=a; lookup in file=prog1 [ ELF ] 17375: symbol=a; lookup in file=./W.so.1 [ ELF ] 17375: binding file=./X.so.1 to file=./W.so.1: symbol `a' ..... 17375: symbol=b; lookup in file=prog1 [ ELF ] 17375: symbol=b; lookup in file=./W.so.1 [ ELF ] 17375: symbol=b; lookup in file=./X.so.1 [ ELF ] 17375: symbol=b; lookup in file=./w.so.1 [ ELF ] 17375: binding file=./X.so.1 to file=./w.so.1: symbol `b'
对函数 a() 或 b() 其中之一的每个引用都会导致从应用程序 prog1 开始搜索关联的符号。对 a() 的每个引用都绑定到在 W.so.1 中发现的符号的第一个实例。对 b() 的每个引用都绑定到在 w.so.1 中发现的符号的第一个实例。此示例揭示了 W.so.1 和 w.so.1 中的函数定义如何插入到 X.so.1 和 x.so.1 中的函数定义。使用直接绑定时会发生插入,这是使用直接绑定时需要考虑的一个重要因素。下面的几节中详细介绍了插入。
此示例很简洁,很容易遵循关联的诊断信息。然而,大多数应用程序是基于许多动态组件构造的,要复杂得多。这些组件是从不同的源根基生成的,通常异步提交。
对来自复杂进程的诊断信息进行分析可能比较有难度。分析动态目标文件的接口需求的另一种方法是使用 lari(1) 实用程序。lari 分析进程的绑定信息以及每个目标文件提供的接口定义。该信息使得 lari 能够简明地转换关于进程符号依赖项的受关注信息。在分析伴随着直接绑定发生的插入时,该信息非常有用。
缺省情况下,lari 将转换它认为受关注的信息。该信息源自一个符号定义的多个实例。lari 为 prog1 揭示以下信息。
$ lari prog1 [2:2ES]: a(): ./W.so.1 [2:0]: a(): ./X.so.1 [2:2E]: b(): ./w.so.1 [2:0]: b(): ./x.so.1
在此示例中,从 prog1 建立的进程包含两个多次定义的符号:a() 和 b()。输出诊断信息中的初始元素(括在方括号中的那些元素)描述了关联的符号。
第一个十进制值表示关联符号的实例数。a() 和 b() 都存在两个实例。第二个十进制值表示已解析为此符号的绑定数。来自 W.so.1 的符号定义 a() 揭示已建立了到此依赖项的两个绑定。同样,来自 w.so.1 的符号定义 b() 揭示已建立了到此依赖项的两个绑定。绑定数之后的字母用于限定绑定。字母 "E" 表示已从外部 (external) 目标文件建立了绑定。字母 "S" 表示已从同一 (same) 目标文件建立了绑定。
在接下来的几节中,将使用 LD_DEBUG、lari 以及从这些组件生成的进程示例来进一步研究直接绑定情况。