gdp调试的基本使用

                                    <div

class=“article-source-link”>

                原文链接:<a href="http://www.cnblogs.com/HKUI/p/8955443.html"

target="_blank"
rel=“noopener”>http://www.cnblogs.com/HKUI/p/8955443.html

            </div>

                    <link

href=“https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css”
rel=“stylesheet”>

            <div

class=“htmledit_views” id=“content_views”>

                               <div

class=“blogpost-body”
id=“cnblogs_post_body”>

GDB调试

启动程序准备调试
GDB
yourpram

或者
先输入GDB
然后输入 file
yourpram

然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传递给该程序

参数列表

命令

命令缩写

命令说明

list

l

显示多行源代码

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.6289
bt
方法同上一个gdb调试

 

转载于:https://www.cnblogs.com/HKUI/p/8955443.html

                                   

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值