Linux下的程序調試:gdb的簡單使用(本文例子使用C程序)

本例在CentOS7 64位環境下。

將用下面的例子做說明,可以跟着圖片一步一步調試。

1.普通傳參(例子1)

// 函數參數傳遞普通值
#include <stdio.h>

void change(int a,int b){
    
	int tmp = a;
    a = b;
	b = tmp;
}

int main(){
    
    int a = 5;
    int b = 3;
    
    change(a,b);
    
    printf("num a = %d \n num b=%d\n",a,b);
}

使用gdb前提:

程序是調試程序,在gcc時加-g,例如當前代碼使用gcc -o main.out -g main.c進行編譯。

啓動程序調試:gdb 程序名

在這裏插入圖片描述

開始運行程序:start

在這裏插入圖片描述

展示代碼:l

在這裏插入圖片描述

運行下一行:n

在這裏插入圖片描述

注意: 輸入n之後打印的那一行代碼,是之後會運行的代碼,此時還沒有運行。

小技巧: 在使用一次n之後,需要再運行n,可以直接按回車,可以省去輸入n的麻煩。這個方法不止適用於n,其它的指令也是同樣的效果(即按回車等於重複執行上一次輸入的命令)。

進入函數:s

當程序運行到第16行的時候,如果使用n,會直接運行到下一行(即不會進入函數中),你看不到函數內是如何運行的。所以當運行到函數的時候,需要使用s進入函數內調試。

在這裏插入圖片描述

獲取變量值:p 變量名

前面的序號$1會一直累加,看後面的結果就好。

在這裏插入圖片描述

顯示函數堆棧:bt

在進入change函數內調試之後,使用bt顯示棧堆。

在這裏插入圖片描述

棧底是main,棧頂是change,當前正在運行change函數。

at後面是函數所在的文件和所在行數。

切換棧位置,獲取棧內變量值:f 堆棧序號

在這裏插入圖片描述

使用f 堆棧序號切換棧位置;使用bt可以獲得函數棧堆,其中的堆棧序號就是這裏的堆棧序號。

切換之後會顯示此棧中運行到哪一行,比如圖中,運行到main棧中的第16行,change函數。

之後可以用p 變量名輸出當前棧中變量的值(圖中有兩個p a,他們代表的變量不是同一個,上面的a是change函數中的,下面的a是main函數中的)。

退出:quit或ctrl+d

2.指針傳參(例子2)

// 函數參數傳遞指針地址
#include <stdio.h>

void change(int *a,int *b){

    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(){


    int a = 5;
    int b = 3;

    change(&a,&b);

    printf("num a = %d \n num b=%d\n",a,b);
}

進入函數:s

在這裏插入圖片描述

a,b的值爲他們的地址,相差4個字節。

獲取指針變量的值:p *指針變量名

在這裏插入圖片描述

注意: 我們使用n,會顯示出一行代碼,這行代碼是將要運行的(即當前還沒有運行),所以*b的值不等於tmp的值。

3.其它筆記

內存最小的單位叫字節Byte(8bit)。

經常這樣:計算用二進制,顯示用十進制,編程用十六進制。

內存管理:

64位操作系統,使用的內存只要有前面的48位就可以了(0x7fffffffffffffff~0x0)。

在這裏插入圖片描述

上面是高位,下面是低位。

系統內核:

棧:保存函數運行的狀態

可分配區域(綠色區域):在堆、棧之間

堆:

數據段:存放全局變量、常量或靜態變量

代碼段:代碼編譯後的二進制數據加載到內存中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章