linux下glibc程序安装、使用及段错误(Segmentation fault (core dumped))解决
在Linux系统下,glibc是非常底层的系统库,一旦出了问题将会导致大多数的linux命令无法使用。升级glibc是非常麻烦的事情,升级成功经常会遇到段错误,本篇文章将会简单介绍一下如何安装glibc以及段错误的原因。
编译安装glibc
下载glibc
下载地址 : 中科大gnu镜像
本文以 glibc-2.17
为例进行编写。
编译glibc
1 | tar xvf glibc-2.17.tar.bz2 #如果解压错误,请尝试 yum install bzip2 安装。 |
依赖库有 gcc
错误: ld.so.conf: No such file or directory
如果执行 make install
报此问题,那么可以复制 /etc下的ld.so.conf到安装目录。
1 | cp /etc/ld.so.* /opt/glibc/etc/ -r |
使用新的glibc生成程序
使用自带的glibc编译程序
- 有一个
gettime.c
文件如下所示
1 |
|
- 编译
1 | gcc ./gettime.c -o gettime |
- 运行
修改 LD_LIBRARY_PATH的方式使用新的glibc
1 | export LD_LIBRARY_PATH=/opt/glibc/lib:$LD_LIBRARY_PATH |
不能直接使用修改LD_LIBRARY_PATH的方式指向新的glibc库,会导致大部分程序无法运行
通过 rpath 和 dynamic-linker 的方式使用新的glibc
使用老的glibc编译
1
gcc gettime.c -o gettime_old
使用新的glibc编译
1
gcc gettime.c -o gettime_new -Wl,--rpath=/opt/glibc/lib -Wl,--dynamic-linker=/opt/glibc/lib/ld-linux-x86-64.so.2
运行结果
时间不一致的原因是因为默认的时区不一致导致的
如果还不够清楚,那么可以去修改glibc的源代码
- 修改
glibc-2.17/time/localtime.c
的 27至 33行
1 | struct tm * |
修改后
1 | struct tm * |
然后重新编译glibc
1 | cd build |
重新编译 gettime.c
,结果如下所示
修改已有程序的glibc链接地址
如果编译好的可执行文件可以修改glibc库,那么就能够达到欺骗程序的时间获取,满足一些特殊场景下的要求。
原理
ld-linux.so.2
的绝对路径在链接时被硬编码到可执行文件中,并且在链接完成后不能轻易更改.
- 查看
gettime_old
的链接器路径,以及 Runpath路径
1 | readelf ./gettime_old -l|grep interpreter |
1 | readelf ./gettime_old -a|grep rpath |
- 查看
gettime_new
的链接器路径,以及Runpath路径
1 | readelf ./gettime_new -l|grep interpreter |
1 | readelf ./gettime_new -a|grep rpath |
总结:
-Wl,--rpath
与LD_LIBRARY_PATH
不是同一种东西- 决定glibc路径的是 interpreter(dynamic-linker)
- glibc中interpreter的路径是硬编码到可执行文件中的
修改 interpreter 与 rpath
patchelf 可以做到修改程序的dynamic-linker,以及rpath(Run path)。
下载
路径为:github下载
下载后直接解压即可
使用
- 修改 interpreter 与 rpath
1 | ./patchelf --set-interpreter /opt/glibc/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc/lib ./gettime_old |
- 查看 interpreter 与 rpath
- 运行
- 可以看到已经修改成功
参考资料
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 豆花的快乐时光!
评论