Linux gdb设置和管理断点

来源:互联网 发布:私有域名解析软件 编辑:程序博客网 时间:2024/06/04 19:59

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 1Type commands for breakpoint(s) 1, one per line.End with a line saying just "end".>silent>printf "value=%d\n", value>end(gdb) n18          getvalue();(gdb) n015      for(i = 0; i < 100; ++i)(gdb) nvalue=0(gdb) n18          getvalue();(gdb) n115      for(i = 0; i < 100; ++i)(gdb) nvalue=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_goprint $arg0continueend
commands 1silentprint_and_goend

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) l6   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) l16      {17          value = i;18          getvalue();19      }20  21      return 0;22  }(gdb) b 16 if i==2Breakpoint 1 at 0x400873: file utbif.cpp, line 16.(gdb) rStarting program: /root/Desktop/51codeclub/test/uttest/t 01Breakpoint 1, main () at utbif.cpp:1717          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) clearDeleted breakpoint 1 (gdb) info breakpointsNo breakpoints or watchpoints.(gdb) whatis atype = long(gdb) whatis itype = int(gdb) watch value==2Hardware watchpoint 2: value==2(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /root/Desktop/51codeclub/test/uttest/t 01Hardware watchpoint 2: value==2Old value = falseNew value = truemain () at utbif.cpp:1818          getvalue();(gdb) p value$2 = 2(gdb) clearNo breakpoint at this line.(gdb) info breakpointsNum     Type           Disp Enb Address            What2       hw watchpoint  keep y                      value==2    breakpoint already hit 1 time(gdb) disdisable      disassemble  disconnect   display      (gdb) disable 2(gdb) b getvalueBreakpoint 3 at 0x400841: file utbif.cpp, line 8.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /root/Desktop/51codeclub/test/uttest/t Breakpoint 3, getvalue () at utbif.cpp:88       cout<<value<<endl;

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