生活随笔
收集整理的這篇文章主要介紹了
gdb调式程序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
gdb調式程序
標簽: listfileubuntugcc優化編譯器 2012-04-09 18:43 2630人閱讀 收藏 舉報
分類: PHP(41) Linux(21)
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
目錄(?)[+]
gdb調式程序
最近要調試PHP源代碼,使用工具GDB.
1.?GDB簡介
GDB是Linux/Unix下一個GNU調試程序,是用來調試C與C++程序的強力調試器。能夠讓用戶在程序運行時觀察程序的內部結構和內存的使用情況。
作用:
1)按照自定義的方式啟動運行需要調試的程序。
2)可以使用指定位置和條件表達式的方式來設置斷點。
3)程序暫停時的值的監視。
4)動態改變程序的執行環境。
2.??基本操作命令:
這里只介紹常用命令的簡單用法,如需讀者想更加深入的了解,還請讀者參照gdb手冊。也可以使用--help查看。
基本命令列表:
| 命令 | 解釋 | 簡寫 |
| file | 裝入想要調試的可執行文件 | 無 |
| list | 列出產生執行文件源代碼的一部分 | l |
| next | 執行一行源代碼但不進入函數內部 | n |
| step | 執行一行源代碼而且進入函數內部 | s |
| run | 執行當前被調試的程序 | r |
| continue | 繼續執行程序 | c |
| quit | 終止GDB | q |
| print | 輸出當前指定變量的值 | p |
| break | 在代碼里設置斷點 | b |
| info break | 查看設置斷點的信息 | i b |
| delete | 刪除設置的斷點 | d |
| watch | 監視一個變量的值,一旦值有變化,程序停住 | wa |
| help | GDB中的幫助命令 | h |
3,編程實例
創建c文件:test.c
[cpp] view plaincopyprint?
#include<stdio.h>??#include<string.h>??void?prints(int?i)??{?????printf("hello?%d\n",?i);??}??void?main?()????{????int?i?=0;????for(i=1;i<6;i++){???????prints(i);????}????}??
編譯,其目標文件為test
gcc -o test test.c
這個程序執行
[cpp] view plaincopyprint?
./test???
時顯示如下結果:
hello 1
hello 2
hello 3
hello 4
hello 5
4 gdb調試程序
如果需要使用gdb調試
在編譯test.c的時候,并把調試選項打開:
[plain] view plaincopyprint?
gcc?-o?-ggdb?test?test.c??
(調試選項資料:
調試選項(DEBUGGING?OPTION)
GNU?CC擁有許多特別選項,既可以調試用戶的程序,也可以對GCC排錯:?
-g?
以操作系統的本地格式(stabs,?COFF,?XCOFF,或DWARF).產生調試信息.?GDB能夠使用這些調試信息.?
在大多數使用stabs格式的系統上,?`-g'選項啟動只有GDB才使用的額外調試信息;這些信息使GDB?調試效果更好,但是有可能導致其他調試器崩潰,或拒絕讀入程序.如果你確定要控制是否生成額外的信息,?使用`-gstabs+',?`-gstabs',?`-gxcoff+',?`-gxcoff',?`-gdwarf+',或`-gdwarf'?(見下文).?
和大多數C編譯器不同,?GNU?CC允許結合使用`-g'和`-O'選項.優化的代碼偶爾制造?一些驚異的結果:某些聲明過的變量根本不存在;控制流程直接跑到沒有預料到的地方;某些語句因為計算結果是常量或已經確定而?沒有執行;某些語句在其他地方執行,因為他們被移到循環外面了.?
然而它證明了調試優化的輸出是可能的.對可能含有錯誤的程序使用優化器是合理的.?
如果GNU?CC支持輸出多種調試信息,下面的選項則非常有用.?
-ggdb?
以本地格式(如果支持)輸出調試信息,盡可能包括GDB擴展.?
)
1)啟動
2)載入文件:file命令
file test
結果:
[plain] view plaincopyprint?
gcc?-o?-ggdb?test?test.c??
也可以通過直接啟動的方式載入文件:
[plain] view plaincopyprint?
root@ubuntu:/opt/c++#?gdb?test??GNU?gdb?(Ubuntu/Linaro?7.2-1ubuntu11)?7.2??Copyright?(C)?2010?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?"i686-linux-gnu".??For?bug?reporting?instructions,?please?see:??<http://www.gnu.org/software/gdb/bugs/>...??Reading?symbols?from?/opt/c++/test...done.??
3)list命令
也可以過回車查看源代碼
[cpp] view plaincopyprint?
(gdb)?list??1???#include<stdio.h>??2???#include<string.h>??3???void?prints(int?i)??4???{??5??????printf("hello?%d\n",?i);??6???}??7???void?main?()??8?????9???{??10????int?i?=0;??(gdb)???
一次只列10行,如果要從11行開始繼續列源代碼可以輸入
(gdb) list
也可以什么都不輸直接敲回車,gdb提供了一個很方便的功能,在提示符下直接敲回車表示用適當的參數重復上一條命令。
回車:
[cpp] view plaincopyprint?
(gdb)?list??1???#include<stdio.h>??2???#include<string.h>??3???void?prints(int?i)??4???{??5??????printf("hello?%d\n",?i);??6???}??7???void?main?()??8?????9???{??10????int?i?=0;??(gdb)???11????for(i=1;i<6;i++){??12???????prints(i);??13????}??14????15??}??16????(gdb)???
4)單步逐條執行 next
首先用start命令開始執行程序:
[plain] view plaincopyprint?
(gdb)?start??Temporary?breakpoint?1?at?0x80483e9:?file?test1.c,?line?10.??Starting?program:?/opt/c++/test1?????Temporary?breakpoint?1,?main?()?at?test1.c:10??10????int?i?=0;??(gdb)???
這表示停在main函數中變量定義之后的第一條語句處等待我們發命令,gdb列出這條語句表示它還沒執行,并且馬上要執行
我們可以用next命令(簡寫為n)控制這些語句一條一條地執行:
[plain] view plaincopyprint?
(gdb)?next??11????for(i=1;i<6;i++){??(gdb)?(直接回車)??12???????prints(i);??(gdb)?????hello?1??11????for(i=1;i<6;i++){??(gdb)???12???????prints(i);??(gdb)???hello?2??11????for(i=1;i<6;i++){??(gdb)???12???????prints(i);??(gdb)???hello?3??11????for(i=1;i<6;i++){??(gdb)???12???????prints(i);??(gdb)???hello?4??11????for(i=1;i<6;i++){??(gdb)???12???????prints(i);??(gdb)???hello?5??11????for(i=1;i<6;i++){??(gdb)???15??}??(gdb)???
5)逐條執行并進入函數:
用start命令重新來過,step命令(簡寫為s)進入 函數中去執行:
[plain] view plaincopyprint?
(gdb)?start??Temporary?breakpoint?2?at?0x80483e9:?file?test1.c,?line?10.??Starting?program:?/opt/c++/test1?????Temporary?breakpoint?2,?main?()?at?test1.c:10??10????int?i?=0;??(gdb)?next??11????for(i=1;i<6;i++){??(gdb)?next??12???????prints(i);??(gdb)?step??prints?(i=1)?at?test1.c:5??5??????printf("hello?%d\n",?i);??(gdb)???
進入到了函數
prints
在函數中有幾種查看狀態的辦法,backtrace命令(簡寫為bt)可以查看函數調用的棧幀:
[plain] view plaincopyprint?
(gdb)?bt??#0??prints?(i=1)?at?test1.c:5??#1??0x08048407?in?main?()?at?test1.c:12??(gdb)???
main傳進來的參數是i=1。main函數的棧幀編號為1,prints的棧幀編號為0。
6)在可以用info命令(簡寫為i)查看局部變量
[plain] view plaincopyprint?
i??locals??
如果想查看main函數當前局部變量的值也可以做到,先用frame命令(簡寫為f)選擇1號棧幀然后再查看局部變量:
[plain] view plaincopyprint?
(gdb)?f?1??#1??0x08048407?in?main?()?at?test1.c:12??12???????prints(i);??(gdb)???
7)輸出當前指定變量的值 print
[plain] view plaincopyprint?
(gdb)?p?i??$1?=?1??(gdb)???
總結
以上是生活随笔為你收集整理的gdb调式程序的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。