首先是要安裝 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 在這裡就不多提了。
沒有留言:
張貼留言