2.gdb 的常用命令 表 1-4 常用的 gdb 命令 命令 解釋 break NUM 在指定的行上設置斷點。 BT 顯示所有的調用棧幀。該命令可用來顯示函數的調用順序。 clear 刪除設置在特定源文件、特定行上的斷點。其用法為:clear FILENAME:NUM。 continue 繼續執行正在調試的程序。該命令用在程序由于處理信號或斷點而 導致停止運行時。 display EXPR 每次程序停止后顯示表達式的值。表達式由程序定義的變量組成。 file FILE 裝載指定的可執行文件進行調試。 help NAME 顯示指定命令的幫助信息。 info break 顯示當前斷點清單,包括到達斷點處的次數等。 info files 顯示被調試文件的具體信息。 info func 顯示所有的函數名稱。 info local 顯示當函數中的局部變量信息。 info prog 顯示被調試程序的執行狀態。 info var 顯示所有的全局和靜態變量名稱。 kill 終止正被調試的程序。 list 顯示源代碼段。 make 在不退出 gdb 的情況下運行 make 工具。 next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。 print EXPR 顯示表達式 EXPR 的值。
★ -O 編譯選項 With `-O', the compiler tries to redUCe code size and execution time. When you specify `-O', the two options `-fthread-jumps' and `-fdefer-pop' are turned on 優化,減少代碼大小和執行的時間 [alert7@redhat62 alert7]$ gcc -O -o test test.c [alert7@redhat62 alert7]$ wc -c test 11757 test [alert7@redhat62 alert7]$ gdb -q test (gdb) disass main Dump of assembler code for function main: 0x80483d8 : push %ebp 0x80483d9 : mov %esp,%ebp 0x80483db : call 0x80483c8 0x80483e0 : xor %eax,%eax 0x80483e2 : leave 0x80483e3 : ret 0x80483e4 : nop ... End of assembler dump. (gdb) disass hi Dump of assembler code for function hi:
★ -O2 編譯選項 -O2 Optimize even more. Nearly all supported optimizations that do not involve a space-speed tradeoff are performed. Loop unrolling and function inlining are not done, for example. As compared to -O, this option increases both compilation time and the performance of the generated code. [alert7@redhat62 alert7]$ gcc -O2 -o test test.c [alert7@redhat62 alert7]$ wc -c test 11757 test [alert7@redhat62 alert7]$ gdb -q test (gdb) disass main Dump of assembler code for function main: 0x80483d8 : push %ebp 0x80483d9 : mov %esp,%ebp 0x80483db : call 0x80483c8 0x80483e0 : xor %eax,%eax 0x80483e2 : leave 0x80483e3 : ret ... 0x80483ef : nop End of assembler dump. (gdb) disass hi Dump of assembler code for function hi: 0x80483c8 : push %ebp 0x80483c9 : mov %esp,%ebp 0x80483cb : push $0x8048440 0x80483d0 : call 0x8048308 0x80483d5 : leave 0x80483d6 : ret 0x80483d7 : nop End of assembler dump. 由于程序比較簡單,再優化也沒有好優化的了,所以跟-O出來的一樣。
★ -fomit-frame-pointer 編譯選項 -fomit-frame-pointer Don't keep the frame pointer in a register for functions that don't need one. This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions. It also makes debugging impossible on most machines. 忽略幀指針。這樣在程序就不需要保存,安裝,和恢復ebp了。這樣ebp也就是一個free的register了,在函數中就可以隨便使用了。
[alert7@redhat62 alert7]$ gcc -fomit-frame-pointer -o test test.c [alert7@redhat62 alert7]$ wc -c test 11773 test [alert7@redhat62 alert7]$ gdb -q test (gdb) disass main Dump of assembler code for function main: 0x80483e0 : call 0x80483d0 0x80483e5 : xor %eax,%eax 0x80483e7 : jmp 0x80483f0 0x80483e9 : lea 0x0(%esi,1),%esi 0x80483f0 : ret .... End of assembler dump. (gdb) disass hi Dump of assembler code for function hi: 0x80483d0 : push $0x8048450 0x80483d5 : call 0x8048308 0x80483da : add $0x4,%esp 0x80483dd : ret 0x80483de : mov %esi,%esi End of assembler dump. 在main()和hi()中都去掉了以下指令 push %ebp mov %esp,%ebp//這兩條指令安裝 leave//這條指令恢復 來看看部分的內存映象 (內存高址) +--------+ bffffbc4 argv的地址(即argv[0]的地址) 0xbffffb84 +--------+ 00000001 argc的值 0xbffffb80 +--------+ 400309cbmain的返回地址 0xbffffb7c +--------+ 080483e5 hi()的返回地址 0xbffffb78 +--------+ 08048450 "hi"字符串的地址 0xbffffb74 +--------+ ...... (內存低址) 沒有保存上層執行環境的ebp.
★ -static 編譯選項 -static On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect. 把一些函數都靜態的編譯到程序中,而無需動態鏈接了。 [alert7@redhat62 alert7]$ gcc -o test -static test.c [alert7@redhat62 alert7]$ wc -c test 962808 test [alert7@redhat62 alert7]$ gdb -q test (gdb) disass main Dump of assembler code for function main: 0x80481b4 : push %ebp 0x80481b5 : mov %esp,%ebp 0x80481b7 : call 0x80481a0 0x80481bc : xor %eax,%eax 0x80481be : jmp 0x80481c0 0x80481c0 : leave 0x80481c1 : ret ... End of assembler dump. (gdb) disass hi Dump of assembler code for function hi:
0x80481a0 : push %ebp 0x80481a1 : mov %esp,%ebp 0x80481a3 : push $0x8071528 0x80481a8 : call 0x804865c 0x80481ad : add $0x4,%esp 0x80481b0 : leave 0x80481b1 : ret 0x80481b2 : mov %esi,%esi End of assembler dump. [alert7@redhat62 alert7]$ ldd test not a dynamic executable -static出來的代碼已經沒有PLT了,GOT雖然有,已經全部為0了。