做网站需要学哪些软件,建设企业网站需要使用哪些技术,中兴通讯的网站建设分析,制作网页的方法出现这种差异的原因在于#xff1a;动态库中的符号分为两种类型#xff1a;
常规符号表#xff08;regular symbol table#xff09;#xff1a;通常用于静态链接和调试#xff0c;默认不包含在动态库中#xff08;除非显式保留#xff09;。动态符号表#xff08;dyn…出现这种差异的原因在于动态库中的符号分为两种类型
常规符号表regular symbol table通常用于静态链接和调试默认不包含在动态库中除非显式保留。动态符号表dynamic symbol table专门用于动态链接始终存在于动态库中供运行时解析符号。
具体解释nm默认查看的是常规符号表
如果动态库在编译时通过-fvisibilityhidden或strip命令移除了常规符号表为减小体积或保护代码nm会显示no symbols。nm -D强制查看动态符号表.dynsym段
动态链接器如ld.so仅依赖动态符号表解析符号因此即使常规符号表被剥离动态符号表仍必须保留除非库被完全strip -R .dynsym但这会导致库无法使用。如何验证检查动态符号表是否存在
readelf -S libxxx.so | grep dynsym
若存在.dynsym段则nm -D必然有输出。检查是否被剥离
file libxxx.so
输出若包含stripped说明常规符号表已被移除但动态符号表可能仍存在。总结
nm看不到符号 → 常规符号表被剥离不影响动态链接。nm -D能看到符号 → 动态符号表正常足够动态链接使用。
这是动态库优化后的正常现象无需担心功能问题。
二、常规符号表的作用
常规符号表regular symbol table通常是.symtab和.strtab段只在静态链接和调试阶段有用对动态库的正常运行完全没有作用。具体用途如下1. 调试Debug
作用为调试器如gdb提供符号信息函数名、变量名、行号等。例子
如果动态库保留了常规符号表调试时可以准确看到崩溃栈中的函数名#0 0x00007ffff7a8b2c4 in my_function() from libxxx.so如果符号表被剥离只能看到地址#0 0x00007ffff7a8b2c4 in ?? from libxxx.so2. 静态链接Static Linking
作用如果某个**静态库.a文件**需要链接这个动态库中的符号常规符号表是必需的。例子
假设libxxx.so中有函数foo()如果另一个静态库libbar.a需要在编译时链接foo()则需要libxxx.so的常规符号表来解析foo()的地址。
但这种情况极少见因为动态库通常不会用于静态链接。3. 分析工具如nm、objdump
作用帮助开发者检查库的内部符号如是否有未导出的全局符号。例子
nm libxxx.so可以查看所有符号包括未导出的而nm -D libxxx.so只能看到动态符号表导出的符号。4. 性能分析Profiling
作用perf等性能分析工具依赖符号表将地址转换为函数名。例子
如果符号表被剥离perf report只能显示十六进制地址无法直观看到热点函数。常规符号表 vs 动态符号表特性常规符号表.symtab动态符号表.dynsym作用调试、静态链接动态链接是否必须存在否可剥离是必须存在工具查看nm、objdump -tnm -D、readelf -sD大小较大含所有符号较小仅导出符号
结论
对最终用户常规符号表完全无用可以安全strip如strip libxxx.so。对开发者建议保留调试版带符号表用于调试发布版剥离符号表以减小体积。