用GDB追蹤glibc代碼執行過程

欲善其事,必先利其器。 首先需要安裝一下額外的工具包,一個是 libc6-dbg,這是帶有debug symbol信息的 libc.so;另一個是libc6-dev,這是glibc的源代碼,獲取之後我們就可以在gdb中查看代碼了。

在Ubuntu/Debian 系統上,我們可以通過以下2條命令獲得:

$sudo apt-get install libc6-dbg
$sudo apt-get source libc6-dev

在Fedora/Red Hat 系的OS上,需要安裝的軟件包的名字不叫 libc6-dbg,libc6-dev,貌似應該是glibc-debuginfo。

之後,以一段小程序為例來演示整個過程,小程序包含了一個系統調用fork(),一個庫函數printf()

  • myprog.c
#include <stdio.h>
#include <unistd.h>

int main() {
    int son;
    if((son=fork())==0)
        printf("I am son\n");
    else
        printf("I am farther\n");
    return 0;
}
gcc -g myprog.c -o myprog

然後開啟gdb調試 $cgdb myprog

  • no debugging symbols found)
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from system-supplied DSO at 0x7ffff7ffe000...(no debugging symbols found)...done.
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6

看來沒有找到 glibc 的 debuginfo

  • /usr/lib/debug/lib64/libc-2.12.so.debug...done.
  • show debug-file-directory
(gdb) show debug-file-directory
The directory where separate debug symbols are searched for is "/usr/local/lib/debug".

(gdb) set debug-file-directory /usr/lib/debug
(gdb) r  有一個再次加載確認
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from system-supplied DSO at 0x7ffff7ffe000...(no debugging symbols found)...done.
Reading symbols from /lib64/libc.so.6...Reading symbols from /usr/lib/debug/lib64/libc-2.12.so.debug...done.
done.
Loaded symbols for /lib64/libc.so.6
  • 先用 set debug-file-directory 測試出對應程式碼路徑
  • ../nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c: No such file or directory.
(gdb) set debug-file-directory /usr/lib/debug
(gdb) start
Temporary breakpoint 1 at 0x40055a: file myprog.c, line 6.
Starting program: /media/shihyu/Toshiba/libc/myprog

Temporary breakpoint 1, main () at myprog.c:6
(gdb) s
__libc_fork () at ../nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c:65
65      ../nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c: No such file or directory.
(gdb)
  • 找到程式碼路徑在 /nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c

  • show directories

Reading symbols from ./myprog...done.
(gdb) set debug-file-directory /usr/lib/debug
(gdb) directory ./eglibc-2.19/nptl
Source directories searched: /media/shihyu/Toshiba/libc/./eglibc-2.19/nptl:$cdir:$cwd
(gdb) show directories
Source directories searched: /media/shihyu/Toshiba/libc/./eglibc-2.19/nptl:$cdir:$cwd
(gdb) start
Temporary breakpoint 1 at 0x40055a: file myprog.c, line 6.
Starting program: /media/shihyu/Toshiba/libc/myprog

Temporary breakpoint 1, main () at myprog.c:6
warning: Source file is more recent than executable.
(gdb) s
__libc_fork () at ../nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c:65
(gdb)

书籍推荐