Linux下gdb调试工具的使用
gdb是GNU開源組織發布的一個強大的Linux下的程序調試工具。
gdb主要完成四個方面的功能:(1)、啟動你的程序,可以按照你的自定義的要求隨心所欲的運行程序;(2)、可讓被調試的程序在你所指定的調試的斷點處停住(斷點可以是條件表達式);(3)、當程序被停住時,可以檢查此時你的程序中所發生的事;(4)、動態的改變你程序的執行環境。
要想運行準備調試的程序,可使用run命令,在它后面可以跟隨發給該程序的任何參數,包括標準輸入和標準輸出說明符(<;和>;)和shell通配符(*、?、[、])在內。如果你使用不帶參數的run命令,gdb就再次使用你給予前一條run命令的參數。利用set? args命令就可以修改發送給程序的參數,而使用show? args命令就可以查看其缺省參數的列表。
一般來說,gdb主要調試的是c/c++的程序,也可以調試Ada、Objective-C、Pascal及其它語言。要調試c/c++的程序,首先在編譯時,我們必須要把調試信息加到可執行文件中。使用編譯器(cc/gcc/g++)的-g(-ggdb)參數可以做到這一點。如果沒有-g,你將看不見程序的函數名、變量名,所代替的全是運行時的內存地址。
啟動gdb的方法:(1)、gdb? <program> :program就是執行文件,一般在當前目錄下;(2)、gdb? <program>? core:用gdb同時調試一個運行程序和core文件,core是程序非法執行后core? dump后產生的文件;(3)、gdb? <program>? <PID> :如果是一個服務程序,你可以指定這個服務程序運行時的進程ID。gdb會自動attach上去,并調試它。
gdb中,輸入命令時,可以不用打全命令,只用打命令的前幾個字符就可以了,當然,命令的前幾個字符應該要標志著一個唯一的命令,在Linux下,可以敲擊兩次Tab鍵來補齊命令的全稱,如果有重復的,那么gdb會把相關的全例出來。
gdb調試中常用的命令:
(1)、l或list命令,查看源碼;
(2)、r或run命令,運行程序,會在有斷點的地方停住,如果是有輸入參數的,則為run? argv[1]? argv[2];
(3)、break? n,在源程序第n行處設置斷點;break? fun,在函數fun()入口處設置斷點;break? filename:function ,在源文件filename的function函數的入口處設置斷點;break filename:linenum ,在源文件filename的第linenum行處設置斷點;break? if<condition>, 在條件成立時停住;filename可以是相對路徑,即你不僅可以在當前原文件中設置斷點,也可以在該程序中用到的其它目錄中的原文件中設置斷點;
(4)、info命令,查看指定命令信息,如info? break會顯示所有設置的斷點信息;
(5)、n或next命令,單條語句執行,如果有函數調用,它不會進入該函數;
(6)、c或continue命令,繼續運行程序;
(7)、p或print 變量名var,打印變量var的值。print是gdb的一個功能很強的命令,利用它可以顯示被調試的語言中任何有效的表達式。表達式除了包含你程序中的變量外,還可以包含以下內容:A、對程序中函數的調用;B、數據結構和其它復雜對象;
(8)、bt或backtrace命令,查看函數調用棧的所有信息,當程序執行異常時,可通過此命令查看程序的調用過程;
(9)、finish命令,運行程序,直到當前函數完成返回;
(10)、q或quit命令,退出gdb;
(11)、set命令,可指定運行時變量名的值;
(12)、watch? <expr>,為表達式(變量)expr設置一個觀察點,一旦表達式的值有變化時,馬上停住程序;rwatch <expr>,當表達式(變量)expr被讀時,停住程序;awatch? <expr>,當表達式(變量)的值被讀或被寫時,停住程序;
(13)、clear命令,清除所有的已定義的停止點,如斷點等;clear?<filename:function>,清除所有設置在函數上的停止點;clear?<filename:linenum>,清除所有設置在指定行上的停止點;
(14)、step命令,單步跟蹤,如果有函數調用,它會進入該函數,如果想退出該函數返回到它的調用函數中,可以使用finish命令;
(15)、jump命令,可以修改程序的執行順序,可以讓程序執行隨意跳躍;
(16)、whatis命令,可以顯示某個變量的類型;
(17)、up和down命令:遍歷函數堆棧,up是將調用棧上移一個函數調用,down是將調用棧下移一個函數調用;
(18)、where命令:查看逆序的調用堆棧信息;
要想了解gdb的更詳細的用法,可以從http://www.gnu.org/software/gdb/documentation/下載gdb? manuals。
以下以一個測試程序為例,說明其中的一些命令的具體用法,此例程的組織結構為:gdbtest為總目錄,下面有include/demo/src三個目錄,(1)、include/add/add.h, include/subtract/subtract.h;(2)、src/add/add.cpp,src/subtract/subtract.cpp;(3)、demo/test/test.cpp。
每個文件的詳細內容為:
add.h:
#ifndef _ADD_H_
#define _ADD_H_int CalAdd(int a, int b);
float CalAdd(float a, float b, float c);#endif //_ADD_H_
subtract.h:
#ifndef _SUBTRACT_H_
#define _SUBTRACT_H_int CalSubtract(int a, int b);
float CalSubtract(float a, float b);#endif //_SUBTRACT_H_
add.cpp:
#include "../../include/add/add.h"int CalAdd(int a, int b)
{int tmp1 = a / 2;if (b % 2 == 1) {b = b * 2 + 3;} else {b = b + 5;}int tmp2 = -1;tmp1 = a + tmp1 + b + tmp2;return tmp1;
}float CalAdd(float a, float b, float c)
{float tmp1 = a - b;for (int i = 0; i < 10; i ++) {float tmp2 = i * 0.5;tmp1 += tmp2;}float tmp2 = a + c - b - tmp1;return tmp2;
}
subtract.cpp:
#include "../../include/subtract/subtract.h"int CalSubtract(int a, int b)
{int tmp1 = 5;while (tmp1) {int tmp2 = 100;a += tmp2 / 2;-- tmp1;}int tmp3 = a - b;return tmp3;
}float CalSubtract(float a, float b)
{float tmp1 = -111;for (int i = 0; i < 100; i ++) {float tmp2 = -199;a -= b;a += tmp2;}float tmp3 = a - b;return tmp3;
}
test.cpp:
#include <iostream>
#include <stdlib.h>
#include "../../include/add/add.h"
#include "../../include/subtract/subtract.h"using namespace std;int main(int argc, char* argv[])
{cout<<"integer test, input integer:"<<endl;int a = 5, b = 10;if (argc > 1)a = atoi(argv[1]);if (argc > 2)b = atoi(argv[2]);int ret = 0;cout<<"start add:"<<endl;ret = CalAdd(a, b);cout<<"integer add :"<<ret<<endl;cout<<"start subtract:"<<endl;ret = CalSubtract(b, a);cout<<"integer subtract:"<<ret<<endl;cout<<"ok!!"<<endl;return 0;
}
打開終端,定位為到/demo/test/目錄下,依次輸入:
g++ -c -g test.cpp ../../src/add/add.cpp ../../src/subtract/subtract.cpp
g++ -o test test.o add.o subtract.o
會在test目錄下生成test.o, add.o, subtract.o和test執行文件。
下面開始調試test:
(1)、輸入gdb?test,會顯示:
(2)、先用l或list命令,查看當前原文件源碼,每次會顯示10行,每次顯示行數也可以設置,如果想繼續查看后面的代碼,可以直接按Enter鍵,表示繼續執行上次輸入的命令:
(3)、為了不讓程序一次性執行完,可以先設置一個斷點,后面根據需要可以隨時再增加斷點,輸入break? 22,在當前文件test.cpp的第22行設置斷點,輸入info?break查看此斷點信息:
(4)、使用run命令開始正式調試test,輸入run?10? 20:
(5)、使用n或next命令,單步調試,接著輸入step命令進入到CalAdd函數內部:
(6)、多設置幾個斷點:break? ../../src/add/add.cpp:13,break ../../subtract/subtract.cpp:5, break 26, 輸入info?break查看:
(7)、輸入finish命令,從CalAdd函數內部退出,使用whatis命令,查看變量ret類型,輸入print?ret查看變量值:
(8)、使用continue命令,執行到下一個斷點設置處:
(9)、使用clear命令,清除指定的斷點:
(10)、如果想從頭再次重新調試程序,可接著輸入run?30? 40,之前設的斷點繼續有效,如退出gdb調試,直接輸入q或quit即可:
參考文獻:
1.?http://www.gnu.org/software/gdb/
2.?http://blog.csdn.net/haoel/article/category/9197
總結
以上是生活随笔為你收集整理的Linux下gdb调试工具的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FFmpeg简介及在vc2010下编译步
- 下一篇: API Sanity Checker在U