gdb咋玩啊

調試器GDB的基本使用方法

main.c:

#include <stdio.h>
#include <stdlib.h>
 
extern int sum(int value);
 
struct inout {
    int value;
    int result;
};

int main(int argc, char * argv[])
{
    struct inout * io = (struct inout * ) malloc(sizeof(struct inout));
    if (NULL == io) {
        printf("Malloc failed.\n");
        return -1;
    }

    if (argc != 2) {
        printf("Wrong para!\n");
        return -1;
    }

    io -> value = *argv[1] - '0';
    io -> result = sum(io -> value);
    printf("Your enter: %d, result:%d\n", io -> value, io -> result);
    return 0;
}

sum.c:

int sum(int value) {
    int result = 0;
    int i = 0;
    for (i = 0; i < value; i++)
        result += (i + 1);
    return result;
}
  • gcc main.c sum.c -o main -g, 得到main可執行文件.
  • 1.1 設置斷點以及 1.3顯示棧幀是常用功能;調試過程中可以需要1.6 單步執行,並且1.4 顯示變量、1.5顯示寄存器、1.8 監視點、1.9 改變變量的值。
    如果進程已經運行中,需要1.11 attach到進程,或者1.10 生成轉儲文件進行分析。當然爲了提高效率可以自定義1.13 初始化文件。

1.1 設置斷點

  • b或者break設置斷點,
break 函數名
break 行號
break 文件名:函數名
break 文件名:行號
break +偏移量
break -偏移量
break *地址
查看斷點,通過info break查看斷點列表。
  • 刪除斷點通過命令包括:
delete <斷點id>:刪除指定斷點
delete:刪除所有斷點
clear
clear 函數名
clear 行號
clear 文件名:行號
clear 文件名:函數名

參考鏈接

  • https://www.cnblogs.com/arnoldlu/p/9633254.html
  • 沒錄完

gdb咋玩啊

  • 首先

  • gcc -g test.c -o test(-g告訴gcc在編譯程序時加入調試信息)

  • 接下來

  • gdb test

  • 然後好多信息在屏幕上,大致說的是gdb的一些版本信息說明之類的,可加上-q,不輸出它們。

  • gdb -q test

在這裏插入圖片描述

(gdb)                                       //list默認一次顯示10行
   #include<stdio.h>
   int func(int n)
   {
       int i;
       int sum=0;
       for(i=0;i<n;i++)
           {
               sum+=i;
           }
       return sum;
(gdb)                                       //直接輸入回車重複上次命令,顯示接下來的10行
   }
   int main()
   {
       int n;
       printf("請輸入n的值");
       scanf("%d",&n);
       printf("1+2+..+%d=%d",n,func(n));
       return 0;
   }
(gdb)

  • list默認參數用show listsize來查看,如果10行太多
    • set listsize 來更改。
  • list 5,10 顯示第5行到第10行的代碼;
  • list func 顯示func函數週圍的代碼,顯示範圍和list參數有關
  • list test.c:5,10 顯示test.c 5到10行代碼,一般用於調試含多個源文件的程序。
  • search str,從當前行開始,向前查找含str的字符串
  • reverse-search str,從當前行開始,向後查找含str的字符串
    現在你的屏幕應該被佔滿了吧?
  • gdb也支持運行linux命令的,輸入shell,然後在輸入你需要的命令就可

(gdb) shell clear

設一個斷點,讓程序停在第6行之前


(gdb) break 6
Breakpoint 1 at 0x80484c8: file test.c, line 6.
(gdb) 
  • 1說明我設置的這個斷點是第一個斷點,斷點所在內存地址爲0x80484c8,test.c的第6行。

  • 條件表達式設置斷點。
(gdb) break 7 if n==6
Breakpoint 2 at 0x80484d1: file test.c, line 7.
(gdb) 

  • 如果n的值爲6,則程序運行到第7行停止。

  • 直接在某個函數處設置斷點;直接break 函數名就可,

  • 看設置的斷點信息,
  • 用info breakpoints
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
      breakpoint     keep y   0x080484c8 in func at test.c:6
      breakpoint     keep y   0x080484d1 in func at test.c:7
    stop only if n==6
      breakpoint     keep y   0x080484c1 in func at test.c:5
(gdb)

  • Num斷點的編號;
  • Type斷點的斷點的類型,第二個斷點類型還加上了條件;
  • Disp中斷點在執行一次之後是否失去作用,dis爲是,keep爲不是;
  • Enb表示當前中斷點是否有效,y爲是,n爲否;

在這裏插入圖片描述

  • 不要程序在該斷點暫停
  • 使該斷點失效,直接刪除該斷點。

(gdb) disable 1
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
      breakpoint     keep n   0x080484c8 in func at test.c:6
      breakpoint     keep y   0x080484d1 in func at test.c:7
    stop only if n==6
      breakpoint     keep y   0x080484c1 in func at test.c:5
(gdb)

  • 第一個斷點的Enb變爲n了,表示該斷點無效,
    • 如果需要恢復,可用enable
  • disable後面的參數爲斷點的編號。而不是行號。
  • 直接刪除該斷點,可使用clear和delete

(gdb) clear 6
已刪除的斷點 1
(gdb)

  • clear後面的參數爲設置斷點的行號,還可以加設置斷點的函數名。
  • delete後面的參數爲斷點的編號;可一次刪除多個斷點,斷點編號之間用空格隔開;如果delete後沒參數,默認刪除所以斷點

調試

(gdb) run                                                //開始執行程序
Starting program: /home/wang/test 
請輸入n的值10

Breakpoint 1, func (n=10) at test.c:6     //設置的第一個斷點,程序在第6行暫停
       for(i=0;i<n;i++)
(gdb) continue                                      //讓程序繼續運行,直到下個斷點或者結束
Continuing.

Breakpoint 2, func (n=10) at test.c:8    //第二個斷點設置的是i==6時停止
               sum+=i;
(gdb) print i                                          //用print命令打印出i的值
$1 = 6
(gdb) print sum
$2 = 15
(gdb) next                                          //繼續執行下一條語句,只執行一條。
       for(i=0;i<n;i++)
(gdb) next    
               sum+=i;
(gdb) print i
$3 = 7
(gdb) continue    
Continuing.
1+2+..+10=45[Inferior 1 (process 23636) exited normally]    
(gdb) quit                                             //退出gdb調試

  • run,開始運行程序;
  • continue,程序暫停時繼續運行程序的命令
  • print 變量名或表達式,打印該變量或者該表達式的值。
    • whatis 變量名或表達式,顯示該變量或表達式的數據類型。
  • print 變量=值,給對應的變量賦值;
    • set variable 變量=值。作用和用print賦值相同
  • next不會跟蹤進入函數
  • step跟蹤進入函數內部。


(gdb) run
Starting program: /home/wang/test 

Breakpoint 1, main () at test.c:16
       scanf("%d",&n);
(gdb) next
請輸入n的值10  
       printf("1+2+..+%d=%d",n,func(n));
(gdb) next                                             //next命令直接執行下一行,沒有進入func函數  
       return 0;
(gdb)

(gdb) run
Starting program: /home/wang/test 

Breakpoint 1, main () at test.c:16
       scanf("%d",&n);
(gdb) n
請輸入n的值10
       printf("1+2+..+%d=%d",n,func(n));
(gdb) step                  //step命令跟蹤進入了func函數  
func (n=10) at test.c:5
       int sum=0;
(gdb)

  • nexti和stepi單步執行一條機器指令

  • quit,退出gdb調試,如果調試中想要退出,可以直接輸入該命令,會出現提示選擇是否退出。

  • kill命令,結束當前程序的調試,(不會退出gdb)

gdb) quit
A debugging session is active.

    Inferior 1 [process 32229] will be killed.

Quit anyway? (y or n) 

參考鏈接

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