首先是要安裝 debug symbols 的套件來使用。
Debian 可以參考 HowToGetABacktrace - Debian Wiki
Ubuntu 可以參考 DebuggingProgramCrash - Ubuntu Wiki
例如目標是 Ubuntu 12.04 中的 Xorg 裡面的 positionSprite() 函式在執行時傳入的變數值,所以先用
$ ps aux | grep X
root 1044 0.4 1.0 127440 21524 tty7 Ss+ 18:44 0:06 /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -background none
u 2633 0.0 0.0 13616 928 pts/2 S+ 19:11 0:00 grep --color=auto X
來找出 Xorg 的 PID
然後執行以下指令:
$ sudo gdb /usr/bin/Xorg 1044
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /usr/bin/Xorg...Reading symbols from /usr/lib/debug/usr/bin/Xorg...done.
done.
Attaching to program: /usr/bin/Xorg, process 1044
Reading symbols from /lib/x86_64-linux-gnu/libudev.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libudev.so.0
... [省略]
(gdb) set height 0
(gdb) break positionSprite
Breakpoint 1 at 0x7fedc71d1140: file ../../dix/getevents.c, line 940.
(gdb) c
Continuing.
Breakpoint 1, positionSprite (dev=0x7fedc94105d0, mode=0, mask=0x7fff3c6e6780, devx=0x7fff3c6e6770, devy=0x7fff3c6e6778, screenx=0x7fff3c6e6760, screeny=0x7fff3c6e6768) at ../../dix/getevents.c:940
940 ../../dix/getevents.c: 沒有此一檔案或目錄.
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>print *devx
>print *devy
>print *screenx
>print *screeny
>continue
>end
(gdb) c
Continuing.
接下來移動滑鼠就可以看到以下的訊息。
Breakpoint 1, positionSprite (dev=0x7fedc94105d0, mode=0, mask=0x7fff3c6e6780, devx=0x7fff3c6e6770, devy=0x7fff3c6e6778, screenx=0x7fff3c6e6760, screeny=0x7fff3c6e6768) at ../../dix/getevents.c:940
940 in ../../dix/getevents.c
$45 = 1023.4510981145139
$46 = 757.60130195816362
$47 = 1366.6023460649326
$48 = 758.58904811456273
Breakpoint 1, positionSprite (dev=0x7fedc94105d0, mode=0, mask=0x7fff3c6e6780, devx=0x7fff3c6e6770, devy=0x7fff3c6e6778, screenx=0x7fff3c6e6760, screeny=0x7fff3c6e6768) at ../../dix/getevents.c:940
940 in ../../dix/getevents.c
$49 = 1022.651098102593
$50 = 757.60130195816362
$51 = 1365.5341153549775
$52 = 758.58904811456273
可以將設定好的 breakpoints 的動作儲存成一個腳本檔
(gdb) save breakpoints break.cmd
Saved to file 'break.cmd'.
腳本的內容是:
set height 0
break positionSprite
commands
print *devx
print *devy
print *screenx
print *screeny
cont
end
只是第一行的 set height 0 是手動加上去的,目的是不要訊息過長就停下來。
下次再使用 GDB 時就可以執行 source 載入使用。
(gdb) source break.cmd
Breakpoint 1 at 0x7fedc71d1140: file ../../dix/getevents.c, line 940.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00007fedc71d1140 in positionSprite at ../../dix/getevents.c:940
print *devx
print *devy
print *screenx
print *screeny
cont
只是前面有一個找不到原始碼的小問題,可以執行以下指令來下載原始碼:
$ apt-get source xserver-xorg-core-lts-quantal
或是:
$ pull-lp-source xorg-server-lts-quantal precise
然後再執行:
$ sudo gdb /usr/bin/Xorg 1044 -d xorg-server-lts-quantal-1.13.0
最後 GDB 有其它的 Frontend 可以使用,像是 cgdb 以及 ddd 在這裡就不多提了。