编译可进行源码级调试的libc库
手动操作过程
-
下载对应版本的libc源码:Index of /gnu/glibc,解压
-
创建两个目录:glibc-2.xx_build,glibc-2.xx_out
-
进入glibc-2.xx_build目录
-
执行:
../glibc-2.xx/configure --prefix=/home/selph/glibcs/glibc-2.xx_out CFLAGS="-Og -g -g3 -ggdb -gdwarf-4" CXXFLAGS="-Og -g -g3 -ggdb -gdwarf-4" --disable-werror
- 为了调试,加了"-g -g3 -ggdb"调试选项,
- -Og是必须得,因为C库必须要指定,否则会报libc/config.h:4:3: error: #error "glibc cannot be compiled without optimization"错误(具体原因可以参考这里:gcc - GLibc optimizations required - Stack Overflow)。
- 最后的--disable-werror也是必须的,否则会将编译过程中的很多警告信息归为错误,那么就没法继续编译了。
- 参考../glibc-2.35/configure --help的提示帮助。
-
执行
make
,make install
-
在out文件夹的lib目录下就是我们编译的libc
参考资料:
遇到的问题
如果configure出错了:
configure: WARNING:
*** These auxiliary programs are missing or incompatible versions: msgfmt makeinfo
*** some features or tests will be disabled.
*** Check the INSTALL file for required versions.
可能需要装几个包:
sudo apt install gettext texinfo
检查安装好了没:
msgfmt --version
makeinfo --version
自动化下载编译脚本
#!/bin/sh
# a function to show usage info
usage() {
# highlight print the usage and author
echo "\033[31mUsage: $0 [version]\033[0m"
echo "Example: $0 2.35"
echo "Author: selph"
exit 1
}
# param check
if [ $# -ne 1 ]; then
usage
fi
# if param is -h or --help, show usage info
if [ $1 = "-h" ] || [ $1 = "--help" ]; then
usage
fi
# check if install, if not install it
# texinfo
if [ ! -x "$(command -v texinfo)" ]; then
sudo apt install texinfo
fi
# gettext
if [ ! -x "$(command -v gettext)" ]; then
sudo apt install gettext
fi
# wget
if [ ! -x "$(command -v wget)" ]; then
sudo apt install wget
fi
# recvice a param named version
version=$1
# split version to url
url="https://ftp.gnu.org/gnu/glibc/glibc-${version}.tar.gz"
# judge the file is exist or not, if not download it
if [ ! -f "glibc-${version}.tar.gz" ]; then
wget $url
fi
# uncompress the file
tar -zxvf glibc-${version}.tar.gz
# create build and out dir
mkdir glibc-${version}_build
mkdir glibc-${version}_out
# get prefix path
prefix=$(pwd)/glibc-${version}_out
# enter build dir and compile
cd glibc-${version}_build
../glibc-${version}/configure --prefix=$prefix CFLAGS="-Og -g -g3 -ggdb -gdwarf-4" CXXFLAGS="-Og -g -g3 -ggdb -gdwarf-4" --disable-werror
make -j12
# make install
# exit build dir
cd ..
# check glibcs dir is exist or not, if not create it
if [ ! -d "glibcs" ]; then
mkdir glibcs
fi
# make a another dir to store all libc's libc.so and ld.so
#cp glibc-${version}_out/lib/libc.so.6 glibcs/libc-${version}.so
#cp glibc-${version}_out/lib/ld-linux-x86-64.so.2 glibcs/ld-${version}.so
# libc.so 就在glibc-2.xx_build目录下
# ld.so 就在glibc-2.xx_build/elf 目录下
# copy libc.so and ld.so to glibcs dir
cp glibc-${version}_build/libc.so glibcs/libc-${version}.so
cp glibc-${version}_build/elf/ld.so glibcs/ld-${version}.so
# check if have trash-cli ,if not using rm command
if [ ! -x "$(command -v trash)" ]; then
rm -rf glibc-${version}_build
else
# remove build dir
trash glibc-${version}_build
# clear trash
trash-empty
fi
自动切换目标程序的libc和ld链接
#!/bin/sh
# This script is used to change the default libc library to the one specified using patchelf
# libc and ld file in glibcs/ld-${version}.so
# param1: filename
# param2: version of libc
# root directary using store libc and ld
root_dir=/home/selph/glibc-self-compile/glibcs
# if param is not 2, print help
if [ $# -ne 2 ]; then
# print banner and help and author selph
echo "Change libc to the specified version"
echo "Usage: $0 [filename] [version]"
echo "Example: $0 a.out 2.35"
echo "Author: selph"
exit 1
fi
# recvice a param named filename and version
filename=$1
version=$2
# patchelf change file's ld
patchelf --set-interpreter ${root_dir}/ld-${version}.so $filename
# patchelf change file's libc
patchelf --replace-needed libc.so.6 ${root_dir}/libc-${version}.so $filename