gdb調試的基本使用

GDB調試
啓動程序準備調試
GDB yourpram
或者
先輸入GDB
而後輸入 file yourpramlinux

而後使用run或者r命令開始程序的執行,也能夠使用 run parameter將參數傳遞給該程序express

參數列表centos

命令ide

命令縮寫函數

命令說明ui

listspa

ldebug

顯示多行源代碼unix

break調試

b

設置斷點,程序運行到斷點的位置會停下來

info

i

描述程序的狀態

run

r

開始運行程序

display

disp

跟蹤查看某個變量,每次停下來都顯示它的值

step

s

執行下一條語句,若是該語句爲函數調用,則進入函數執行其中的第一條語句

next

n

執行下一條語句,若是該語句爲函數調用,不會進入函數內部執行(即不會一步步地調試函數內部語句)

print

p

打印內部變量值

continue

c

繼續程序的運行,直到遇到下一個斷點

set var name=v

 

設置變量的值

start

st

開始執行程序,main函數的第一條語句前面停下來

file

 

裝入須要調試的程序

kill

k

終止正在調試的程序

watch

 

監視變量值的變化

backtrace

bt

查看函數調用信息(堆棧)

frame

f

查看棧幀  f n 切換到編號爲n的棧

quit

q

退出GDB環境

 

  

//e.c
 #include <stdio.h>
void debug(char *str)
{
    printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
    int i,j;
    j=0;
    for(i=0;i<10;i++){
        j+=5;
        printf("now a=%d\n", j);
    }
}

gcc -g -o e e.c
調試gdb e
或者輸入gdb
而後 file e

list 命令用法

list命令顯示多行源代碼,從上次的位置開始顯示,默認狀況下,一次顯示10行,第一次使用時,從代碼起始位置顯示

gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
10            j+=5;
(gdb) 

list n顯示已第n行未中心的10行代碼

(gdb) list 8
3    {
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
10            j+=5;
11            printf("now a=%d\n", j);
12        }
(gdb) 

list functionname顯示以functionname的函數爲中心的10行代碼

(gdb) list main
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
10            j+=5;
(gdb) 

list - 顯示剛纔打印過的源代碼以前的代碼

(gdb) list 10
5    }
6    main(int argc,char *argv[]){
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
10            j+=5;
11            printf("now a=%d\n", j);
12        }
13    }(gdb) list -
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
(gdb) 

斷點命令break
break location:在location位置設置斷點,該位置能夠爲某一行,某函數名或者其它結構的地址
GDB會在執行該位置的代碼以前停下來

gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
10            j+=5;
(gdb) 
11            printf("now a=%d\n", j);
12        }
13    }(gdb) break 10
Breakpoint 1 at 0x40050a: file e.c, line 10.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e 

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
(gdb) c
Continuing.
now a=5

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
(gdb) c
Continuing.
now a=10

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
(gdb) 
View Code

使用delete breakpoints 斷點號 刪除斷點
這裏的斷點號表示的是第幾個斷點,剛纔執行break 10返回 reakpoint 1 at 0x40050a: file e.c, line 10.
中的1表示該斷點的標號,所以使用 delete breakpoints 1表示刪除第10行所定義的斷點
clear n表示清除第n行的斷點,所以clear 10等同於delete breakpoints 1
disable/enable n表示使得編號爲n的斷點暫時失效或有效
可以使用info查看斷點相關的信息
info breakpoints

gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break 10
Breakpoint 2 at 0x40050a: file e.c, line 10.
(gdb) break 9
Breakpoint 3 at 0x400501: file e.c, line 9.
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040050a in main at e.c:10
3       breakpoint     keep y   0x0000000000400501 in main at e.c:9

display命令
查看參數的值

(gdb) break 10
Breakpoint 1 at 0x40050a: file e.c, line 10.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e 

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
(gdb) display j
1: j = 0
(gdb) c
Continuing.
now a=5

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
1: j = 5
(gdb) display
1: j = 5
(gdb) display i
2: i = 1
(gdb) display j
3: j = 5
(gdb) display j*2
4: j*2 = 10
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
4:   y  j*2
3:   y  j
2:   y  i
1:   y  j
View Code

也能夠使用disable,enable,delete,info命令修改及查看其狀態,用法與對斷點的同樣

step及next命令
step可以使得程序逐條執行,即執行完一條語句而後在嚇一跳語句前停下來,等待用戶的命令
通常使用step命令是,可以使用display或者watch命令查看變量的變化,從而判斷程序行爲是否符合要求
當下一條指令爲函數時,s進入函數內部,在其第一條語句前停下來
step n,next n 表示連續但不執行n條指令,若是期間遇到斷點,則停下來

(gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    
7    main(int argc,char *argv[]){
8        int i,j;
9        j=0;
10        for(i=0;i<10;i++){
(gdb) 
11            j+=5;
12            printf("now j=%d\n", j);
13            debug("x=======x");
14        }
15    }(gdb) 
Line number 16 out of range; e.c has 15 lines.
(gdb) break 11
Breakpoint 1 at 0x40050a: file e.c, line 11.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:11
11            j+=5;
(gdb) s
12            printf("now j=%d\n", j);
(gdb) s
__printf (format=0x400648 "now j=%d\n") at printf.c:30
30    {
(gdb) bt
#0  __printf (format=0x400648 "now j=%d\n") at printf.c:30
#1  0x0000000000400525 in main (argc=1, argv=0x7fffffffe538) at e.c:12
(gdb) n
34      va_start (arg, format);
(gdb) n
35      done = vfprintf (stdout, format, arg);
(gdb) n
now j=5
39    }
(gdb) bt
#0  __printf (format=<value optimized out>) at printf.c:39
#1  0x0000000000400525 in main (argc=1, argv=0x7fffffffe538) at e.c:12
(gdb) n
main (argc=1, argv=0x7fffffffe538) at e.c:13
13            debug("x=======x");
(gdb) n
debug info :x=======x
10        for(i=0;i<10;i++){
(gdb) s

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:11
11            j+=5;
(gdb) s
12            printf("now j=%d\n", j);
(gdb) n
now j=10
13            debug("x=======x");
(gdb) n
debug info :x=======x
10        for(i=0;i<10;i++){
(gdb) 
View Code

watch
watch可設置觀察點(watchpoint)。使用觀察點能夠使得當某表達式的值發生變化時,程序暫停執行。
執行該命令前,必須保證程序已經運行

(gdb) list 
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    
7    main(int argc,char *argv[]){
8        int i,j;
9        j=0;
10        for(i=0;i<10;i++){
(gdb) 
11            j+=5;
12            printf("now j=%d\n", j);
13            debug("x=======x");
14        }
15    }(gdb) 
Line number 16 out of range; e.c has 15 lines.
(gdb) b main
Breakpoint 1 at 0x4004fa: file e.c, line 9.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:9
9        j=0;
(gdb) watch j
Hardware watchpoint 2: j
(gdb) c
Continuing.
Hardware watchpoint 2: j

Old value = 0
New value = 5
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=5
debug info :x=======x
Hardware watchpoint 2: j

Old value = 5
New value = 10
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
View Code

print命令

(gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    
7    main(int argc,char *argv[]){
8        int i,j;
9        j=0;
10        for(i=0;i<10;i++){
(gdb) 
11            j+=5;
12            printf("now j=%d\n", j);
13            debug("x=======x");
14        }
15    }(gdb) 
Line number 16 out of range; e.c has 15 lines.
(gdb) break 12
Breakpoint 1 at 0x40050e: file e.c, line 12.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) p j
$1 = 5
(gdb) c
Continuing.
now j=5
debug info :x=======x

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) p i,j
$2 = 10
(gdb) p j
$3 = 10
(gdb) 
View Code

set var name=value

set args 可指定運行時參數(當main函數須要參數時 如:set args 10 20 30 40 50)

show args 命令能夠查看設置好的運行參數


在程序運行中動態改變變量的值

(gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    
7    main(int argc,char *argv[]){
8        int i,j;
9        j=0;
10        for(i=0;i<10;i++){
(gdb) 
11            j+=5;
12            printf("now j=%d\n", j);
13            debug("x=======x");
14        }
15    }(gdb) 
Line number 16 out of range; e.c has 15 lines.
(gdb) break main
Breakpoint 1 at 0x4004fa: file e.c, line 9.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:9
9        j=0;
(gdb) watch i
Hardware watchpoint 2: i
(gdb) watch j
Hardware watchpoint 3: j
(gdb) c
Continuing.
Hardware watchpoint 3: j

Old value = 0
New value = 5
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=5
debug info :x=======x
Hardware watchpoint 2: i

Old value = 0
New value = 1
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10
10        for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j

Old value = 5
New value = 10
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=10
debug info :x=======x
Hardware watchpoint 2: i

Old value = 1
New value = 2
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10
10        for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j

Old value = 10
New value = 15
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=15
debug info :x=======x
Hardware watchpoint 2: i

Old value = 2
New value = 3
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10
10        for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j

Old value = 15
New value = 20
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=20
debug info :x=======x
Hardware watchpoint 2: i

Old value = 3
New value = 4
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10
10        for(i=0;i<10;i++){
(gdb) set var i=8
(gdb) c
Continuing.
Hardware watchpoint 3: j

Old value = 20
New value = 25
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=25
debug info :x=======x
Hardware watchpoint 2: i

Old value = 8
New value = 9
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10
10        for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j

Old value = 25
New value = 30
main (argc=1, argv=0x7fffffffe538) at e.c:12
12            printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=30
debug info :x=======x
Hardware watchpoint 2: i

Old value = 9
New value = 10
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at e.c:10
10        for(i=0;i<10;i++){
(gdb) c
Continuing.

Watchpoint 2 deleted because the program has left the block in
which its expression is valid.

Watchpoint 3 deleted because the program has left the block in
which its expression is valid.
__libc_start_main (main=0x4004eb <main>, argc=1, ubp_av=0x7fffffffe538, init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>, 
    stack_end=0x7fffffffe528) at libc-start.c:258
258      exit (result);
(gdb) c
Continuing.

Program exited with code 026.
View Code

函數調用相關的
backtrace
可以使用frame 查看堆棧中某一幀的信息

(gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
4        printf("debug info :%s\n",str );
5    }
6    
7    main(int argc,char *argv[]){
8        int i,j;
9        j=0;
10        for(i=0;i<10;i++){
(gdb) 
11            j+=5;
12            printf("now j=%d\n", j);
13            debug("x=======x");
14        }
15    }(gdb) 
Line number 16 out of range; e.c has 15 lines.
(gdb) b 13
Breakpoint 1 at 0x400525: file e.c, line 13.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 
now j=5

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:13
13            debug("x=======x");
(gdb) s
debug (str=0x400652 "x=======x") at e.c:4
4        printf("debug info :%s\n",str );
(gdb) bt
#0  debug (str=0x400652 "x=======x") at e.c:4
#1  0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13
(gdb) s
__printf (format=0x400638 "debug info :%s\n") at printf.c:30
30    {
(gdb) bt
#0  __printf (format=0x400638 "debug info :%s\n") at printf.c:30
#1  0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:4
#2  0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13
(gdb) s
34      va_start (arg, format);
(gdb) bt
#0  __printf (format=0x400638 "debug info :%s\n") at printf.c:34
#1  0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:4
#2  0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13
(gdb) s
35      done = vfprintf (stdout, format, arg);
(gdb) s
_IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:236
236      int save_errno = errno;
(gdb) bt
#0  _IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:236
#1  0x000000333a24effa in __printf (format=<value optimized out>) at printf.c:35
#2  0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:4
#3  0x000000000040052f in main (argc=1, argv=0x7fffffffe538) at e.c:13
(gdb) c
Continuing.
debug info :x=======x
now j=10

Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:13
13            debug("x=======x");
(gdb) bt
#0  main (argc=1, argv=0x7fffffffe538) at e.c:13
View Code

 GDB段錯誤調試

所謂段錯誤就是對內存的非法訪問
採用GDB調試段錯誤有2種方法
1.在GDB中運行目標程序,當發生段錯誤時,GDB中運行的程序會自動停下來
2.直接運行目標程序,使其在發生段錯誤時產生內存轉儲(core dump)文件,GDB對該文件進行調試

abort.c

#include <stdio.h>
#include <stdlib.h>

void recurse(void)
{
    static int i;
    if( ++i == 3)
        abort();
    else
        recurse();
}
int main(int argc,char ** argv){
    recurse();
}
gcc -g -o abort abort.c
使用gdb調試
Line number 15 out of range; abort.c has 14 lines.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/abort 

Program received signal SIGABRT, Aborted.
0x000000333a232495 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64      return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) bt
#0  0x000000333a232495 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x000000333a233c75 in abort () at abort.c:92
#2  0x00000000004004e7 in recurse () at abort.c:8
#3  0x00000000004004ec in recurse () at abort.c:10
#4  0x00000000004004ec in recurse () at abort.c:10
#5  0x0000000000400502 in main (argc=1, argv=0x7fffffffe528) at abort.c:13 顯示在recurse函數調用了3次後調用了abort函數,產生段錯誤

使用內存轉儲文件

ulimit -a 

[root@centos1 gcc]# ulimit -a 
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7331
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7331
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
core file size 此時是0

ulimit -c unlimited  設置爲不受限制

 

執行 ./abort 產生內存轉儲文件
ls 可看到一個名爲core且以進程號爲後綴的文件

 

core.6289
gdb abort core.6289bt方法同上一個gdb調試

相關文章
相關標籤/搜索