Linux共享库概述( 九 )


/lib/ld-linux.so.2- 文件路径路径可执行只需执行ld-linux.so而不使用参数即可提供更多的使用帮助 , 但是再一次不要使用它来进行正常使用 - 这些都是用于调试的 。
3.3.2 。 LD_DEBUGGNU C加载器中的另一个有用的环境变量是LD_DEBUG 。 这会触发dl *函数 , 以便他们提供关于他们正在做什么的相当详细的信息 。 例如:
导出LD_DEBUG =文件command_to_run在处理库时显示文件和库的处理 , 告诉您哪些依赖关系被检测到 , 哪些SO以什么顺序加载 。 将LD_DEBUG设置为“bindings”显示有关符号绑定的信息 , 将其设置为“libs” , 显示库搜索路径 , 并将ti设置为“`versions”显示版本依赖 。
将LD_DEBUG设置为“帮助” , 然后尝试运行程序将列出可能的选项 。 再次 , LD_DEBUG不适用于正常使用 , 但在调试和测试时可以方便 。
其他环境变量实际上还有一些控制加载过程的其他环境变量; 他们的名字以LD_或RTLD_开头 。 大多数其他的是用于低级别的加载程序调试或用于实现专门的功能 。 他们大多没有文件证明; 如果您需要了解它们 , 了解它们的最佳方式是读取装载器的源代码(gcc的一部分) 。
如果不采取特殊措施 , 允许用户控制动态链接的库对于setuid / setgid程序将是灾难性的 。 因此 , 在GNU加载程序(程序启动时加载程序的其余部分)中 , 如果程序为setuid或setgid , 那么这些变量(和其他类似的变量)将被忽略或受到很大的限制 。 加载程序通过检查程序的凭据来确定程序是否被setuid或setgid; 如果uid和euid不同 , 或者gid和egid不同 , 那么加载器会假定程序是setuid / setgid(或者从一个下降的) , 因此极大地限制了其控制链接的能力 。 如果您阅读GNU glibc库源代码 , 可以看到这一点; 特别看到文件elf / rtld.c和sysdeps / generic / dl-sysdep.c 。 这意味着如果你使uid和gid等于euid和egid , 然后调用一个程序 , 这些变量就会有效果 。 其他类Unix系统处理不同的情况 , 但出于同样的原因:setuid / setgid程序不应该受到环境变量集的不当影响 。
创建共享库创建共享库很容易 。 首先 , 使用gcc -fPIC或-fpic标志创建将进入共享库的对象文件 。 -fPIC和-fpic选项可以实现“位置独立代码”生成 , 这是共享库的一个要求; 见下文的差异 。 您使用-Wl gcc选项传递soname 。 -Wl选项将选项传递给链接器(在这种情况下为-soname链接器选项) - -Wl之后的逗号不是打字错误 , 并且您不能在选项中包含未转义的空格 。 然后使用以下格式创建共享库:
gcc -shared -Wl , -soname , your_soname \-o library_namefile_listlibrary_list这是一个例子 , 它创建两个对象文件(ao和bo) , 然后创建一个包含它们的共享库 。 请注意 , 此编译包括调试信息(-g) , 并将生成警告(-Wall) , 这些共享库不是必需的 , 但建议使用 。 编译生成对象文件(使用-c) , 并包含所需的-fPIC选项:
gcc -fPIC -g -c -Wall acgcc -fPIC -g -c -Wall bcgcc -shared -Wl , -soname , libmystuff.so.1 \-o libmystuff.so.1.0.1 ao bo -lc这里有几点值得注意: