GDB調試
啟動程序准備調試
GDB yourpram
或者
先輸入GDB
然后輸入 file yourpram
然后使用run或者r命令開始程序的執行,也可以使用 run parameter將參數傳遞給該程序
參數列表
命令 |
命令縮寫 |
命令說明 |
list |
l |
顯示多行源代碼 |
break |
b |
設置斷點,程序運行到斷點的位置會停下來 |
info |
i |
描述程序的狀態 |
run |
r |
開始運行程序 |
display |
disp |
跟蹤查看某個變量,每次停下來都顯示它的值 |
step |
s |
執行下一條語句,如果該語句為函數調用,則進入函數執行其中的第一條語句 |
next |
n |
執行下一條語句,如果該語句為函數調用,不會進入函數內部執行(即不會一步步地調試函數內部語句) |
|
p |
打印內部變量值 |
continue |
c |
繼續程序的運行,直到遇到下一個斷點 |
set var name=v |
|
設置變量的值 |
start |
st |
開始執行程序,在main函數的第一條語句前面停下來 |
file |
|
裝入需要調試的程序 |
kill |
k |
終止正在調試的程序 |
watch |
|
監視變量值的變化 |
backtrace |
bt |
產看函數調用信息(堆棧) |
frame |
f |
查看棧幀 |
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
#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;
(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)
使用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
也可以使用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)
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);
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)
set var name=value
在程序運行中動態改變變量的值
(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.
函數調用相關的
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