当前位置:

Linux环境下的C/C++基础调试技术2——程序控制

2011/11/18 23:02:56  作者:炉石    阅读:2599

1.让程序停下来的三种模式

  • 断点(breakpoint):让程序在特定的地点停止执行。
  • 观察点(watchpoint):让程序在特定的内存地址(或者是一个涉及多个地址的表达式)的值发生变化时停止执行。注意,你不能给一个尚没有在栈帧中的表达式或变量设定观察点,换句话说,常常在程序停下来后才去设置观察点。在设定观察点后,栈帧中不存在所监控的变量时,观察点自动删除。
  • 捕捉点(catchpoint):让程序在发生特定事件时停止执行。

注:

  • GDB文档中统称这三种程序暂停手段为breakpoint,例如在GDB的delete命令的帮助手册中就是这么描述的,它实际上指代的是这三种暂停手段,本文中以breakpoints统称三种模式,以中文进行分别称呼。
  • GDB执行程序到断点(成为断点被hit)时,它并没有执行断点指向的那一行,而是将要指向断点指向的那一行。
  • GDB是以机器指令为单位进行执行的,并非是以程序代码行来进行的,这个可能会带来一些困惑,下文有例子详述。

2.GDB breakpoints的查看

命令:i b = info breakpoints。返回列表每一列的含义如下:

  • Identifier :breakpoints的唯一标识。
  • Type :该breakpoints属于上述三种模式中的哪一个(breakpoint, watchpoint, catchpoint)
  • Disposition:该breakpoints下次被hit以后的状态(keep,del,dis分别对应保留、删除、不使能)
  • Enable Status:该breakpoints是否使能。
  • Address:该breakpoints物理地址。
  • Location :若属于断点则指的是断点在哪个文件的第几行,若是观察点则指的是被观察的变量

3.GDB 程序控制的设置

  • 断点设置:
    • 设置普通断点:break function/line_number/filename:line_number/filename:function. 该断点在被删除或不使能前一直有效。
    • 设置临时断点:tbreak function/line_number/filename:line_number/filename:function. 该断点在被hit一次后自动删除。
    • 设置一次性断点:enable once breakpoint-list,这个与临时断点的不同是该断点会在被hit一次后不使能,而不是删除。
    • 设置正则表达式断点:rbreak regexp 注意该正则表达式是grep型的正则,不是perl或shell的正则语法。
    • 设置条件断点:break break-args if (condition) ,例如break main if argc > 1。
      • 这个与观察点不同的是,观察点只要所观察的表达式或变量的值有变化程序就停下,而条件断点必须满足所指条件。条件断点在调试循环的时候非常有用,例如break if (i == 70000) 。
      • 在已经添加的断点上加上条件使用cond id condition,例如:cond 3 i == 3;想去掉条件转化为普通断点则直接使用cond id,例如,cond 3。
      • 注意,这里的条件外的括号有没有都行,条件中可以使用<, <=, ==, !=, >, >=, &&, ||,&, |, ^, >>, <<,+, -, x, /, %等运算符,也可以使用方法,例如:break test.c:myfunc if ! check_variable_sanity(i),这里的方法返回值一定要是int,否则该条件就会被误读。
    • 删除断点:
      • delete breakpoint_list 列表中为断点的ID,以空格隔开
      • delete 删除全部断点
      • clear 删除下一个GDB将要执行的指令处的断点
      • clear function/filename:function/line_number/filename:line_number 删除特定地点的断点
    • 使能断点:enable breakpoint-list
    • 不使能断点:disable breakpoint-list
    • 跳过断点:ignore id numbers 表示跳过id表示的断点numbers次。
    • 注意:
      • 若设置断点是以函数名进行的话,C++中函数的重载会带来麻烦,该同名函数会都被设置上断点。请使用如下格式在C++中进行函数断点的设置:TestClass::testFunc(int)
      • 设置的断点可能并非是你想放置的那一行。例如:
         
        							
         
        							  1: int main(void) 
        
         
        							  2: { 
        
         
        							  3:     int i; 
        
         
        							  4:     i=3; 
        
         
        							  5:     return 0; 
        
         
        							  6: }

        版权所有 © 2019 光锥极客  津ICP备18001186号-3

        津公网安备 12011202000279号