1. 获取glibc源码
官网:
- https://www.gnu.org/software/libc/
- https://www.gnu.org/software/libc/sources.html
FTP:https://ftp.gnu.org/gnu/glibc/
编译教程:https://sourceware.org/glibc/wiki/Testing/Builds
手册:https://www.gnu.org/software/libc/manual/
从ftp下载即可,我下载的是2.27版本。
2. 配置及编译
解压后阅读一下根目录的INSTALL文档,第一段就强调不能在源码目录里编译,需要在目录之外新建一个目录来存放编译的中间文件,我新建了一个glibc-build-2.27。
必要的configure参数是–prefix指定安装目录,以及其它建议带上的参数:
--disable-werror 避免高版本gcc把警告当成错误
--disable-profile 不要碰配置信息
其余一堆参数默认值即可,比如:
--with-headers=/usr/include
--with-binutils==/usr/bin
编译参数,可以加个-jN用多个线程编译,但我虚拟机是单核的,就不带了。
依赖的工具有gawk。
sudo apt install gawk
mkdir glibc-build-2.27 && cd glibc-build-2.27
../glibc-2.27/configure --prefix=/usr/local/glibc-2.27 --disable-profile --disable-werror
make
make install
安装结果
/usr/local/glibc-2.27$ ll
total 40
drwxr-xr-x 10 root root 4096 Apr 7 08:09 ./
drwxr-xr-x 14 root root 4096 Apr 7 08:08 ../
drwxr-xr-x 2 root root 4096 Apr 7 08:09 bin/
drwxr-xr-x 2 root root 4096 Apr 7 08:09 etc/
drwxr-xr-x 21 root root 4096 Apr 7 08:09 include/
drwxr-xr-x 4 root root 4096 Apr 7 08:09 lib/
drwxr-xr-x 3 root root 4096 Apr 7 08:08 libexec/
drwxr-xr-x 2 root root 4096 Apr 7 08:09 sbin/
drwxr-xr-x 5 root root 4096 Apr 7 08:09 share/
drwxr-xr-x 3 root root 4096 Apr 7 08:09 var/
/usr/local/glibc-2.27$ ll lib
...
-rwxr-xr-x 1 root root 1387616 Apr 7 08:09 ld-2.27.so*
lrwxrwxrwx 1 root root 10 Apr 7 08:09 ld-linux-x86-64.so.2 -> ld-2.27.so*
...
-rwxr-xr-x 1 root root 16804448 Apr 7 08:09 libc-2.27.so*
-rw-r--r-- 1 root root 41556482 Apr 7 08:09 libc.a
-rw-r--r-- 1 root root 306 Apr 7 08:08 libc.so
lrwxrwxrwx 1 root root 12 Apr 7 08:09 libc.so.6 -> libc-2.27.so*
3. 源码调试
gdb
配置LD_LIBRARY_PATH环境变量,使用自己编译的glibc库:
export LD_LIBRARY_PATH=/usr/local/glibc-2.27/lib/
gdb调试个helloworld, 可以顺利走进/libio/ioputs.c:
0x7ffff7a8cbfd <puts+13> call *ABS*+0x83ff0@plt <*ABS*+0x83ff0@plt>
► 0x7ffff7a8cc02 <puts+18> mov rbp, qword ptr [rip + 0x341c3f] <0x7ffff7dce848>
0x7ffff7a8cc09 <puts+25> mov rbx, rax
0x7ffff7a8cc0c <puts+28> mov eax, dword ptr [rbp]
0x7ffff7a8cc0f <puts+31> mov rdi, rbp
0x7ffff7a8cc12 <puts+34> and eax, 0x8000
0x7ffff7a8cc17 <puts+39> jne puts+134 <puts+134>
────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]────────────────────────────────────────────────────────────────────────────────────────
In file: /home/starr/Documents/CProject/glibc-2.27/libio/ioputs.c
31 int
32 _IO_puts (const char *str)
33 {
34 int result = EOF;
35 _IO_size_t len = strlen (str);
► 36 _IO_acquire_lock (_IO_stdout);
37
38 if ((_IO_vtable_offset (_IO_stdout) != 0
39 || _IO_fwide (_IO_stdout, -1) == -1)
40 && _IO_sputn (_IO_stdout, str, len) == len
41 && _IO_putc_unlocked ('\n', _IO_stdout) != EOF)
────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────────────────────────────────────
...
──────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]──────────────────────────────────────────────────────────────────────────────────────────
► f 0 0x7ffff7a8cc02 puts+18
f 1 0x55555555464a main+16
f 2 0x7ffff7a40a87 __libc_start_main+231
vscode
在launch.json里配置环境变量:
"environment": [
{
"name" : "LD_LIBRARY_PATH",
"value": "${LD_LIBRARY_PATH}:/usr/local/glibc-2.27/lib/"
}
],
在printf这里按F11步入,也能走进/libio/ioputs.c,就不截图了。