ldd命令用来查看二进制文件所依赖的动态库,大家经常使用,ldd命令的输出却有些让人迷惑如:
root@LAPTOP-2MOIS3PQ:/home/li# ldd `which ls`
linux-vdso.so.1 (0x00007fffd7cf7000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fbc41220000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbc40e20000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fbc40ba0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbc40990000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbc41800000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbc40770000)
可以看到,第一行与倒数第二行的格式与其他行不一样,没有=>这个箭头,同时,倒数第二行的so带的是绝对路径,其他行却不是,下面来解释一下:
第一行的linux-vdso.so.1,名字是虚拟动态共享库,他其实是内核负责自动映射到用户进程空间的,这个文件存在内核空间中,文件系统中并不能找到这个文件(我在本地是没有find到,内核从哪里加载的呢?未知,可能是直接作为内核模块进去的),这个动态库主要的功能是减小系统调用的开销,例如一些函数调用会使进程进入内核态,读取一些数据等,进入内核态的开销是很大的,所以一些常用的函数调用结果,可以从这个地址空间中直接读取,避免了陷入内核态。
第二行的/lib64/ld-linux-x86-64.so.2写的是全路径,跟其他的库写法也不同,后面没有=>,这里先解释一下=>是什么意思,这代表动态库在文件系统中的位置,这是因为加载动态库时,二进制文件中本身并没有写全路径,所以需要链接器去在一些目录中搜索(LD_LIBRARY_PATH,这个环境变量就可以提供,当然不止这一个),这个库就是链接器本身,他负责找其他库,所以在二进制文件中他是硬编码的,写好了路径,所以他不再需要到文件系统中寻找。