是GLIBC的版本多还是miku的版本多?pixiv:67650124
glibc位置
这个不同系统不一致,linux中比较多的存在于/lib/libc.so.6
想要查找libc的位置可以通过ldd(linux)/otool(mac)查看依赖于libc.so的库(有的库会静态塞进去,此类的是看不了)
有的时侯ldd听到的错误信息也会包含glibc的路径,这种还是按照不同的情况来查找
确认当前环境glibc版本信息
ldd --version
复制
#include
#include
int main()
{
printf("%s", gnu_get_libc_version());
}
复制
二者都可以
GLIBCVersion兼容性
本质上这是一个so的不同版本兼容性问题。一般我们看见的so的版本号是主版本号.次版本号,例如说2.6。链接的时侯只会进行主版本号的判定,不同主版本号可能是不兼容的(不管实际怎样,我们都应当视为不兼容,链接器也会报错的)。而次版本号保证新版本会兼容旧版本,例如说2.6兼容2.4
关于自己编译的库查看GLIBC的依赖
简单的命令查看
strings libxxx.so | grep "^GLIBC"
复制
你会看见多个版本号linux标准教程,因为新版本兼容旧版本,因而其中最新的一个GLIBC版本号是我们所须要的。这时你可能有好多小问号linux查看库版本,让我们一个一个的来解决
自己的库的GLIBCVersion如何来的?
里面也提到了次版本号会高版本兼容低版本,而且假如依赖高版本的却运行于低版本时可能会出现找不到符号的情况,因而引入了基于符号的版本机制。即对应符号可以依赖于某个特定的次版本号
我们从一个反例来将这种串联上去。以下以前面提及过的确认当前环境GLIBC信息的示例代码为例linux查看库版本,实际GLIBC版本大机率不会相同,与你的系统环境有关
首先使用strings查看,可以看见搜到了两个版本
GLIBC_2.2.5
GLIBC_2.34
复制
其实我想你可能早已尝试过后面确认当前版本GLIBCVersion的命令,发觉这儿的符号和当前版本的符号并不相同。我们先讲解这种版本的来源,然后才会明白缘由了
这么为何会有两个版本呢?两个版本又是如何来的呢?让我们用nm查看一下其中的符号
000000000000039c r __abi_tag
0000000000004038 B __bss_start
0000000000004038 b completed.0
w __cxa_finalize@GLIBC_2.2.5
0000000000004028 D __data_start
0000000000004028 W data_start
0000000000001080 t deregister_tm_clones
00000000000010f0 t __do_global_dtors_aux
0000000000003df0 d __do_global_dtors_aux_fini_array_entry
0000000000004030 D __dso_handle
0000000000003df8 d _DYNAMIC
0000000000004038 D _edata
0000000000004040 B _end
0000000000001170 T _fini
0000000000001140 t frame_dummy
0000000000003de8 d __frame_dummy_init_array_entry
00000000000020a8 r __FRAME_END__
0000000000004000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000002008 r __GNU_EH_FRAME_HDR
U gnu_get_libc_version@GLIBC_2.2.5
0000000000001000 T _init
0000000000002000 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U __libc_start_main@GLIBC_2.34
0000000000001149 T main
U printf@GLIBC_2.2.5
00000000000010b0 t register_tm_clones
0000000000001050 T _start
0000000000004038 D __TMC_END__
复制
可以看见__cxa_finalize,gnu_get_libc_version,printf是基于2.2.5,而__libc_start_main是基于2.34,这刚好与我们上面看见的符号相关联。
见到这儿你应当早已明白了,自己的库中GLIBC版本是来始于所使用的符号所标注的版本linux移植,因而我们在当前环境编下来的库的依赖版本实际上是当前环境的库中对应符号所依赖的版本号
libc.so与libc.so.6
libc.so其实长得像so,但它并不是,甚至不是一个软链接。内容大致是这样的
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /usr/lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /usr/lib/ld-linux-x86-64.so.2 ) )
复制
参考资料
程序员的自我修养:链接、装载与库