1. 程式人生 > >GDB常用命令使用說明(一)

GDB常用命令使用說明(一)

本文由霸氣的菠蘿原創,轉載請註明出處:http://www.cnblogs.com/xsln/p/gdb_instructions1.html

GDB(GNU Debugger)是在Unix以及類Unix系統下的除錯工具。功能極其強大,幾乎涵蓋了你所需要的全部功能。 
GDB主要幫忙你完成下面四個方面的功能: 
1.啟動你的程式,可以按照你的定製要求隨心所欲的執行程式。 
2.可讓被除錯的程式在你所指定的調置的斷點處停住。 
3.當程式被停住時,可以檢查此時你的程式中所發生的事,以及記憶體狀態等。 
4.動態的改變你程式的執行環境。

gdb使用總旨:help指令很強大!多用help!help裡面總會有你需要的資訊。如果你不知道如何使用help,請在gdb裡面輸入:help all

 一、gdb使用前置條件:編譯時加入debug資訊。

    gcc/g++是在編譯時加入-g,其他語言請自行百度。值得注意的是,-g分4個等級:

  1. -g0等於不加-g。即不包含任何資訊
  2. -g1只包含最小資訊,一般來說只有你不需要debug,只需要backtrace資訊,並且真的很在意程式大小,或者有其他保密/特殊需求時才會使用-g1。
  3. –g2為gdb預設等級,包含絕大多數你需要的資訊。
  4. –g3包含一些額外資訊,例如包含巨集定義資訊。當你需要除錯巨集定義時,請使用-g3

二、gdb最常見的幾個用法:

     1. 除錯程式。有幾種方法可以在gdb下執行你的程式:

        1)    gdb ${你的程式} 進入gdb後,輸入run(簡寫r) ${arg1} ${arg2} … ${argN}

        2)    gdb --args ${你的程式} ${arg1} ${arg2} … ${argN} 進入gdb後,執行run。

        3)    gdb進入gdb後,輸入file ${你的程式}。然後使用set args  ${arg1} ${arg2} … ${argN} 設定好你的程式引數,再執行run。

     2. 除錯正在執行的程式:

        gdb ${你的程式} ${程式pid}

     3. 查core:

        gdb ${你的程式} ${core檔案}

三、gdb常用命令:

     1. backtrace:顯示棧資訊。簡寫為bt。

     2. frame x 切換到第x幀。其中x會在bt命令中顯示,從0開始。0表示棧頂。簡寫為f。

     3. up/down x 往棧頂/棧底移動x幀。當不輸入x時,預設為1。

     4. print x列印x的資訊,x可以是變數,也可以是物件或者陣列。簡寫為p。

     5. print */&x 列印x的內容/地址。

     6. call 呼叫函式。注意此命令需要一個正在執行的程式。

     7. set substitute-path from_path  to_path,替換原始碼檔案路徑。當編譯機與執行程式的機器程式碼路徑不同時,需要使用該指令替換程式碼路徑,否則你無法在gdb中看到原始碼。

     8. break x.cpp:n 在x.cpp的第n行設定斷點,然後gdb會給出斷點編號m。命令可簡寫為b。後面會對break命令進行更詳細的解釋。

     9. command m 設定程式執行到斷點m時要看的內容,例如:

        command n

          >printf "x is %d\n",x

          >c

          >end

        如果command後面沒有引數n,則命令被賦給最後一個breakpoint,這其實是說break和command連在一起用,在腳本里用就非常方便了。gdb指令碼會在後面詳細介紹

     10. x /nfu ${addr} 列印addr的內容。addr可以是任何合法的地址表示式,例如0x562fb3d,一個當前有效的指標變數p,或者一個當前有效的變數var的地址&var。nfu是格式,n表示檢視的長度,F表示格式(例如16進位制或10進位制),U表示單位(例如單位元組b,雙字h,四字w等)。舉個栗子:

           (gdb) x /3xw 0x562fb3d //這個指令的意思為:以16進位制格式顯示地址0x562fb3d處3個單位,每個單位四位元組的內容。你將得到下列數值:

           0x562fb3d:    0x00282ff4    0x080484e0    0x00000000

     11. continue 繼續執行程式。進入除錯模式後,若你已經獲取了你需要的資訊或者需要程式繼續執行時使用。可簡寫為c

     12. until 執行到當前迴圈完成。可簡寫為u

     13. step 單步除錯,步入當前函式。可簡寫為s

     14. next 單步除錯,步過當前函式。可簡寫為n

     15. finish 執行到當前函式返回

     16. set var x=10 改變當前變數x的值。也可以這樣用:set {int}0x83040 = 10把記憶體地址0x83040的值強制轉換為int並賦值為10

     17. info locals 列印當前棧幀的本地變數

     18. jump使當前執行的程式跳轉到某一行,或者跳轉到某個地址。由於只會使程式跳轉而不會改變棧值,因此若跳出函式到另外的地方 會導致return出錯。另外,熟悉彙編的人都知道,程式執行時,有一個暫存器用於儲存當前程式碼所在的記憶體地址。所以,jump命令也就是改變了這個暫存器中的值。於是,你可以使用“set $pc”來更改跳轉執行的地址。如: set $pc = 0x485

     19. return: 強制函式返回。可以指定返回值

 四、程式中斷機制:監視點(watchpoint)、斷點(breakpoint)和捕捉點(catchpoint):

      1. 監視點。監視點是監視記憶體中某個地址,當該地址的資料被改變(或者被讀取)時,程式交出控制權進入偵錯程式。注意監視點分為軟體模式和硬體模式:GDB 使用軟體監視點的方式是在單步執行你的程式的同時測試變數的值,所以執行程式的速度會變慢。同時,軟體監視點僅在當前執行緒有效。幸運的是,32 位的 Intel x86 處理器提供了 4 個特殊的除錯暫存器用來方便除錯程式,GDB 可以使用這些暫存器建立硬體監視點。GDB 總是會優先使用硬體監視點,因為這樣不會減慢程式的執行速度。然而,可用的(enable的)硬體監視點的個數是有限的。如果你設定了過多的硬體監視點,當程式從中斷的狀態變為執行的狀態(例如continue,until或者finish)時,GDB 可能無法把它們全部啟用。另外,活動的硬體監視點的數量只有在試圖繼續執行程式時才能知道,也就是說,即使你設定了過多的硬體監視點,gdb在你執行程式之前也不會警告你。

        設定監視點的命令有3個,watch(寫監視),rwatch(讀監視)以及awatch(讀寫監視)。他們的使用方法一樣,皆為以下幾種:

        1) (r/a)watch x。x是一個變數名。當x的值改變/被讀取時,程式交出控制權進入偵錯程式。

        2) (r/a)watch 0xN。N為一個有效地址。當該地址的內容變化/被讀取時,程式交出控制權進入偵錯程式。

        3) (r/a)watch *(int *)0xN。N為一個有效地址。當該地址的中的int指標指向的內容變化/被讀取時,程式交出控制權進入偵錯程式。

        4) (r/a)watch -l *(int *)0xN。N為一個有效地址。當該地址的中的int指標指向的內容變化/被讀取,或者該地址的內容變化/被讀取時,程式交出控制權進入偵錯程式。

        注意3)和4)的區別在於,當加入-l選項後,會同時監視表示式本身以及表示式指向的內容。

     2. 斷點是指當執行到程式某一步時,程式交出控制權進入偵錯程式。值得注意的是,break會有一些變體:tbreak,hbreak,thbreak與rbreak。tbreak與break功能相同,只是所設定的斷點在觸發一次後自動刪除。hbreak是一個硬體斷點。thbreak則既是一個臨時的硬體斷點。注意硬體斷點需要硬體支援,某些硬體可能不支援這種型別的斷點。rbreak稍微特殊一些,它會在匹配正則表示式的全部位置加上斷點,後面會有詳細講解。除去rbreak,其他break家族的使用方法如下:

        1) (t/h)break x.cpp:y 。在程式碼x.cpp的第y行加入斷點。x.cpp若不指定,則會以當前執行的檔案作為斷點檔案。若程式未執行,則以包含main函式的原始碼檔案作為斷點檔案。若x.cpp和y都不指定,則以當前debugger的點作為斷點處。

        2) (t/h)break 0xN。在地址N處加入斷點。N必須為一個有效的程式碼段(code segment)地址。

        3) (t/h)break  x.cpp:func。在x.cpp的func函式入口處加入斷點。x.cpp可以不提供直接使用break func。注意由於過載(overload)的存在,因此gdb可能會詢問你希望在哪個函式加上斷點。你也可以通過指定引數型別來避免該問題,例如break func(int ,char *)

        4) (t/h)break  +/-N。在當前執行處的第N行後/前加入斷點。

        5) rbreak REGEXP。 在所有符合正則表示式REGEXP的函式入口加入斷點。例如rbeak EX_* 表示在所有符合以EX_開頭的函式入口處加入斷點。

        注意break後面還有2個可選引數,執行緒id和條件。執行緒id指在info threads中的執行緒序號,而非系統提供的tid。例如break x.cpp:y 2 if (a==24),表示在2號執行緒的x.cpp的第y行加入斷點,並且只有當a的值為24時,程式才會交出控制權進入偵錯程式。

        另外,breakpoints可以通過save命令儲存,以方便使用者下次再次進入程式除錯時不需要重設斷點。

     3. 捕捉點是當某些事件發生時,程式交出控制權進入偵錯程式。例如catch一個exception,assert,signal,fork甚至syscall。tcatch與catch功能一樣,只是所設定的捕捉點在觸發一次後自動刪除。以後會詳細介紹catchpoint。

五、跟蹤點(tracepoint):

     跟蹤點與上面三個斷點不同之處在於,它只是跟蹤記錄資訊而不會中斷程式的執行。當你的程式是realtime程式,或者與其他的程式有互動時,你可能會希望使用跟蹤點達到監視程式而又不破壞程式自身行為的目的。與斷點相同的是,跟蹤點會儲存下在跟蹤點時的一些記憶體資訊供使用者查閱,例如陣列或者物件。

     另外,tracepoints可以通過save命令儲存,以方便使用者下次再次進入程式除錯時不需要重設這些跟蹤點。

六、檢查點(checkpoint):

     gdb可以儲存某一個時間點的程式狀態或者說是程式映像,並且稍後又可以返回到這個狀態。這個稱之為checkpoint。

     每個檢查點是程序的一個拷貝。這樣當一個bug很難重現,而又擔心除錯過頭了又要從頭開始重現時,可以在估計要重現這個bug之前,做一個checkpoint,這樣即使debug過頭了,也可以從這個checkpoint開始,而不用重啟整個程式並且期待它重現這個bug(也許需要很久!!)。

     但是每個checkpoint有一個唯一的程序id,這個pid與原始程式的pid不同,因此如果程式需要使用pid的資訊時,需要慎重考慮。

相關推薦

linux常用命令雜記--Lsof

linux 根據 打開文件 cte data 由於 uid 內部 方法 lsof的用法 lsof全名list opened files,也就是列舉系統中已經被打開的文件。linux環境中,任何事物都是文件,設備是文件,目錄是文件,甚至sockets也是文件。所以,用好lso

Git 常用命令總結

一、設定基本資訊 git config --global user.name "xiaobu" git config --global user.email "[email protected]" 檢視配置資訊 git config --list 設定本地

Linux基礎之常用命令整理

Linux 作業系統的安裝   如今比較流線的linux作業系統 Centos Redhat  Fedora Ubuntu, 安裝作業系統的提前是要有作業系統的映象檔案(.iso檔案)並且必須為系統指定一個啟動盤;    Linux系統的安裝(公司只允許命令列模式)分為典型安裝和自定義安裝,一般

Git常用命令

No1:使用場景:拉取別人的專案 把專案克隆一下 git clone 倉庫地址 (. ) //點表示克隆當前目錄 //如果寫目錄名字表示把這個倉庫克隆到以這個名字為檔名稱

sqoop 常用命令整理

這些內容是從sqoop的官網整理出來的,是1.4.3版本的Document,如果有錯誤,希望大家指正。      1.使用sqoop匯入資料  sqoop import --connect jdbc:mysql://localhost/db --username foo --

windows下rabbitmq 常用命令整理

rabbitmq服務的啟動 啟動伺服器的方式有兩種,一種為dos視窗,以命令列的方式啟動,命令為 rabbitmq-server [-detached] ,加-detached為後臺執行模式,如下

Android常用adb命令總結

ADB是android sdk裡的一個工具,用這個工具可以直接操作管理android模擬器或者真實的andriod裝置。 ADB是一個客戶端-伺服器端程式,其中客戶端是你用來操作的電腦,伺服器端是android裝置。 它的主要功能有: 執行裝置的shell(命令列)

kafka 常用運維命令介紹

文章目錄 一、連線zk zkCli 命令 二、topic 相關 列出所有的topic & 獲取命令幫助 建立topic 列出所有topic的詳情 刪除topic

常用SQL命令彙總-增刪改及單表查詢

一、資料庫及表的建立 資料庫操作: 1、顯示所有資料庫:Show databases; 2、建立資料庫:Create database 資料庫名; 3、刪除資料庫:Drop database 資料庫名; 表操作: CREATE TABLE 表名(  屬性名 資料表

Logstash語法常用案例解析

logstash摘要簡述logstash的常用插件,以及簡單的使用案例一:基礎運行建議使用supervisor來管理ELK中的各個組件,方便同一管理安裝 https://www.aolens.cn/?p=809 有講解提供一個常用的配置:[program:logstash] command=/opt

Linux進程相關的內容及命令小結

進程 linux概念:進程,一個活動的程序實體的副本,擁有生命周期,一個進程可能包含一個或多個執行流; 進程的創建進程: 每個進程的組織結構是一致的; 內核在正常啟動並且全面接管硬件資源之後,會創建一個Init的進程;而這個名叫init的進程負責用戶空間的進程管理; CentOS5及以前:SysV In

linux命令小結

命令 linux 基礎 1)pwd:顯示工作目錄路徑語法: pwd [選項]選項: -L 目錄鏈接時,輸出鏈接路徑 -P 輸出物理路徑例子: [[email protected]/* */ ~]# pwd /root //顯示當前路徑2)

linux常用命令整理:shell基礎

程序猿 逆向 多條 希望 正則表達 group 運行 ls命令 交互式 大家好,我是會唱歌的程序猿~~~~~~ 最近在學習linux,閑暇之余就把這些基本的命令進行了整理,希望大家能用的上,整理的的目的是在忘了的時候翻出來看看^?_?^,前後一共分為五個部分

Linux基礎之常見命令用法

linux基礎命令入門(一)一、Linux文件目錄結構 在講述之前,先簡短的說說Windows文件結構,打開‘計算機’,看到的一個個的驅動器(盤符,例C盤、D盤等),點開其中任意盤符,看到的是一個個文件或文件夾,繼續打開...,每個盤都有自己的根目錄。若是把其打開過程畫下來,便可得到如下多棵倒樹並列的圖

shell中條件測試常用的語法

shell中條件測試常用的語法     shell   bashshell中條件測試常用的語法(一)執行條件測試表達式後通常會返回“真”或“假”,就像執行命令後的返回值為0表示真,非0表示假一樣。在bash編程裏,條件測試常用的語法形式如下:說明:(1)語法1與語法2是等價的,

Oracle 常用命令筆記1

數據庫 oracle 命令說明crsctl start has 啟動數據庫HAS服務。crsctl stat res -t 檢查ASM中的各服務(DG、監聽、ASM實例等)狀態。srvctl status asm 查看ASM實例狀態,正常情況下主備機的ASM實例都應該處於啟動狀態。s

Visual Stdio C++ 編譯器、鏈接器常用命令

線程 dna pretty 文件 入口 all 如果 name -o2 以前使用 Visual Stdio 都是在 IDE 環境下。這兩天編譯 GSL 感覺用 IDE 環境特別不方便,所以就花了點時間簡單學習了如何在命令行下使用 Visual Stdio C++ 編譯器、連

git 命令

IT 暫存區 round 不同版本 版本控制 p s OS ref 修改 1. 版本回退 在實際工作中,我們腦子裏怎麽可能記得一個幾千行的文件每次都改了什麽內容,不然要版本控制系統幹什麽。版本控制系統肯定有某個命令可以告訴我們歷史記錄,在Git中,我們用 git log

virsh的詳細命令解析

tcp ret 解析 auto 綁定 運行 ssi tty 網絡 virsh的詳細命令解析 virsh 有命令模式和交互模式如果直接在vrish後面添加參數是命令模式,如果直接寫virsh,就會進入交互模式 virsh list 列出所有的虛擬機,虛擬機的狀態有(8)種

linux基本命令總結

所在 ons 重復 輸入 結構 統計文件 數據連接 可選 多行 基本命令1.Linux的基本原則:1、由目的單一的小程序組成;組合小程序完成復雜任務;2、一切皆文件;3、盡量避免捕獲用戶接口;(盡量不和用戶進行交互,就是一個程序一但開始運行,就不需要用戶進行任何操作,如ls