Linux gdb设置和管理断点

1.以行号设置断点

(gdb)break 7
(gdb)run

2.以函数名设置断点

(gdb)break function_name
(gdb)run

3.以条件表达式设置断点

(1)break if

(gdb)break 7 if i==99
(gdb)run

(2)condition

break if类似,只是condition只能用在已存在的断点上。
用法:
condition <break_list> (condition)
例如:
cond 3 i == 3
将会在断点3上附加条件(i == 3

(3)条件表达式的返回值

面的条件表达式计算后结果的类型是什么?答案是int型。
这是因为唯一能在断点条件表达式中使用的返回值类型为int。
这意味着,如果调用了像cos()这样的数学函数,会导致预料之外的值。
如(在已经连接到libm库的前提下):

(gdb) print cos(0.0)
$1 = -1073776640

解决这个问题的方法是类型转换,我们来看这个例子

(gdb) set $p = (double (*) (double)) cos
(gdb) print cos(0.0)
$2 = -1073776640
(gdb) print $p(0.0)
$3 = 1

5.为断点设置命令列表

我们知道,设置一个断点并且在上面中断后,我们必然会查询一些变量或者做一些其他动作。
如果这些动作可以一气呵成,岂不妙哉!使用命令列表(commands)就能实现这个功能。

步骤如下:

建立断点
使用commands命令
用法:
commands break_list
例如:

   (gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>printf "value=%d\n", value
>end
(gdb) n
18          getvalue();
(gdb) n
0
15      for(i = 0; i < 100; ++i)
(gdb) n
value=0
(gdb) n
18          getvalue();
(gdb) n
1
15      for(i = 0; i < 100; ++i)
(gdb) n
value=1

6.监视点(watch)

用法:
watch var
注意

监视点的设定不依赖于断点的位置,但是与变量的作用域有关,也就是说,要设置监视点必须在程序运行时才可设置。
在不确定发生问题的地方时,通过使用监视点的条件表达式,可以非常方便地找出问题代码:

watch i > 999

一旦i > 999,程序就会被中断,GDB指出改变条件的代码。

7.使中断失效(断点仍然存在)或有效

(gdb)info breakpoints
(gdb)disable b_id           //使中断失效,b_id 为中断编号
(gdb)info breakpoints
(gdb)enable b_id         //使中断有效,b_id 为中断编号
(gdb)info breakpoints

8.定义宏(define)

宏可以在调试期间录制,也可以事先录制在.gdbinit文件中。
GDB的宏就像shell脚本一样,可以传入参数,依次是 arg0, arg1, …
定义好宏之后,可以用在命令列表中。
注意,宏并不支持所有的GDB命令,如silent就不能用在宏中。
以上节为例,我们录制一个宏:

define print_and_go
print $arg0
continue
end
commands 1
silent
print_and_go
end

9.删除断点

clear : 删除程序中所有的断点
clear 行号 : 删除这行的断点
clear 函数名 : 删除该函数的断点
delete b_id1 b_id2 ... : 删除指定编号的断点

10.查看和设置变量值

(1)print命令

    print 变量或表达式:打印变量或表达式当前的值
    print 变量=值:对变量进行赋值。
    print 表达式@要打印的值的个数n:打印以表达式开始的n个数

(2)whatis命令:显示某个变量或表达式值的数据类型

       whatis 变量或表达式

举个例子

先贴代码

#include <iostream>
using namespace std;

static int value;

void getvalue()
{
    cout<<value<<endl;
}

int main()
{
    int i;
    long a;
    for(i = 0; i < 100; ++i)
    {
        value = i;
        getvalue();
    }

    return 0;
}

调试:

(gdb) l
6   void getvalue()
7   {
8       cout<<value<<endl;
9   }
10  
11  int main()
12  {
13      int i;
14      long a;
15      for(i = 0; i < 100; ++i)
(gdb) l
16      {
17          value = i;
18          getvalue();
19      }
20  
21      return 0;
22  }
(gdb) b 16 if i==2
Breakpoint 1 at 0x400873: file utbif.cpp, line 16.
(gdb) r
Starting program: /root/Desktop/51codeclub/test/uttest/t 
0
1

Breakpoint 1, main () at utbif.cpp:17
17          value = i;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7.x86_64 libgcc-4.8.5-11.el7.x86_64 libstdc++-4.8.5-11.el7.x86_64
(gdb) p value
$1 = 1
(gdb) clear
Deleted breakpoint 1 
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) whatis a
type = long
(gdb) whatis i
type = int
(gdb) watch value==2
Hardware watchpoint 2: value==2
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/Desktop/51codeclub/test/uttest/t 
0
1
Hardware watchpoint 2: value==2

Old value = false
New value = true
main () at utbif.cpp:18
18          getvalue();
(gdb) p value
$2 = 2
(gdb) clear
No breakpoint at this line.
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
2       hw watchpoint  keep y                      value==2
    breakpoint already hit 1 time
(gdb) dis
disable      disassemble  disconnect   display      
(gdb) disable 2
(gdb) b getvalue
Breakpoint 3 at 0x400841: file utbif.cpp, line 8.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/Desktop/51codeclub/test/uttest/t 

Breakpoint 3, getvalue () at utbif.cpp:8
8       cout<<value<<endl;

还有部分内容可以参考http://lesca.me/archives/gdb-breakpoints-command-list-watchpoint.html

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值