1. 程式人生 > >【軟體開發底層知識修煉】十六 快速學習GDB除錯三 使用GDB的資料斷點監測變數是否改變

【軟體開發底層知識修煉】十六 快速學習GDB除錯三 使用GDB的資料斷點監測變數是否改變

文章目錄

1 GDB的資料斷點

先來了解一下什麼是GDB中的資料斷點:

  • 在GDB中設定資料斷點用於監測一個記憶體中的變數,在程式執行的時候,如果該變數被改變,則程式就會被GDB終止執行,並顯示變數被改變的地方。
  • 資料斷點的本質是硬體斷點
  • 在GDB中使用watch命令來設定資料斷點
  • watch命令的用法為:watch var_name

可以使用watch進行設定資料斷點,我們還可以檢視程式執行中的所有記憶體中的資料。

命令語法為:

  • x /Nuf address

其中/Nuf中的N、u、f三個位置的含義是:

  • N - 需要列印的單元數
  • u - 每個單元的大小,比如位元組,字,雙字等
  • f - 資料列印的格式 ,如八進位制,十六進位制等

如下圖示例是顯示4個單元,每個單元為1位元組,以十六進位制數顯示:
在這裡插入圖片描述

  • x 命令中引數u對應的幾種單位:
    在這裡插入圖片描述

  • 列印格式對應的幾種選項:
    在這裡插入圖片描述

1.1 利用檢視記憶體的x命令進行系統大小端的判斷

學會了x命令的用法,可以按如下圖的方式判斷系統大小端:

在這裡插入圖片描述

2 使用GDB進行監視變數的改變與檢視記憶體實際程式碼案例分析

watch.c程式

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int g_var = 0; void* thread_func(void* args) { sleep(5); g_var = 1; } int main() { int i = 0; pthread_t tid = 0; pthread_create(&tid, NULL, thread_func, NULL); for(i=0; i<10; i++) { printf("g_var = %d\n", g_var); sleep(1); } }

上面的程式非常的簡單,就是在main函式中建立一個執行緒thread_func,然後在thread_func函式中改變一個全域性變數

首先我們先編譯執行上述程式:

  • gcc -g -lpthread watch.c -o test.out

執行結果如下動態圖:
在這裡插入圖片描述

  • 我們可以看出,我們程式跑著跑著g_var變數就變了。假設這個變數我們不想讓它改變,但是有時候你呼叫了其他人寫的介面函式,很有可能就把我們不想改變的變數改變了,所以這個時候需要找到變數在什麼時候被改變,以及在哪裡被改變。

  • 上述是一個小程式所以我們很容易知道是在thread_func函式中改變的g_var變數,而且也能夠知道在什麼時候變數被改變。但是如果在一個大型程式中,就很難查詢。

  • 此時GDB的資料斷點就派上用場了。

我們可以使用GDB對變數g_var進行資料斷點的設定,當g_var發生變化時,程式就會自動停止執行,此時我們就可以知道程式執行到哪裡了。

首先依次輸入以下命令:

  • gdb tset.out
  • start

進入到GDB除錯模式並啟動程式後再程式入口處停止。
然後使用watch命令對g_var變數設定資料斷點:

  • watch g_var

  • 並使用info breakpoints 檢視斷點是否設定成功
    上述步驟如下圖所示:
    在這裡插入圖片描述

  • 打好資料斷點後讓程式執行,輸入continue命令即可,顯示如下動態圖所示:
    在這裡插入圖片描述

  • 上述動態圖中,執行著執行著就停止了,停止後顯示如下:
    在這裡插入圖片描述

  • 從上述圖中我們可以知道在watch.c程式的thread_func函式中的12行,導致了g_var的改變,是從Old value=0改變到New value=1的。我們很容易就找到了發生改變的地方,如果在大型程式中,這是很快。

  • 當然,我們還可以使用上面學習的 x 命令,來檢視g_var所在記憶體的內容。首先我們需要檢視g_var變數的的記憶體地址:

  • print /a &g_var 輸入這條命令,顯示如下:
    在這裡插入圖片描述

  • 得到g_var的地址後,使用 x 命令檢視它的記憶體,檢視方式是4單元,1位元組,16進位制方式,如下圖:
    在這裡插入圖片描述

  • 很明顯,我們顯示了g_var記憶體地址的連續4位元組的內容。

  • 到此,我們已經通過這個簡單的示例,學會了如何檢測程式執行過程中的記憶體變化。例子隨簡單,但是也能夠提現記憶體監測的重要性。

3 總結

  • 本文學會使用GDB 進行記憶體監測
  • 學會如何使用GDB資料斷點除錯程式

本文章參考狄泰軟體學院相關課程
想學習的可以加狄泰軟體學院群,
群聊號碼:199546072

學習探討加個人(可以免費幫忙下載CSDN資源):
qq:1126137994
微信:liu1126137994
學習交流資源分享qq群:962535112