GDB笔记(二):条件断点、命令列表、监视点
条件断点
break if
用法:
break [break-args] if (condition)
例如:
break main if argc > 1 break 180 if (string == NULL && i < 0) break test.c:34 if (x & y) == 1 break myfunc if i % (j + 3) != 0 break 44 if strlen(mystring) == 0
condition
与break if类似,只是condition只能用在已存在的断点上。
用法:
condition <break_list> (condition)
例如:
cond 3 i == 3
将会在断点3上附加条件(i == 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
在这里,通过设置变量$p为“一个参数为double,返回类型为double的指向cos函数入口地址的函数指针”,来对参数进行强制类型转换。
为断点设置命令列表
我们知道,设置一个断点并且在上面中断后,我们必然会查询一些变量或者做一些其他动作。
如果这些动作可以一气呵成,岂不妙哉!使用命令列表(commands)就能实现这个功能。
步骤如下:
- 建立断点
- 使用commands命令
用法:
commands break_list
例如:
(gdb) commands 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >silent >printf "n = %d \n", n >continue >end
定义宏(define)
宏可以在调试期间录制,也可以事先录制在.gdbinit文件中。
GDB的宏就像shell脚本一样,可以传入参数,依次是$arg0, $arg1, …
定义好宏之后,可以用在命令列表中。
注意,宏并不支持所有的GDB命令,如silent就不能用在宏中。
以上节为例,我们录制一个宏:
define print_and_go print $arg0 continue end
然后在断点1处定义如下命令:
commands 1 silent print_and_go end
监视点(watch)
用法:
watch var
注意
监视点的设定不依赖于断点的位置,但是与变量的作用域有关,也就是说,要设置监视点必须在程序运行时才可设置。
在不确定发生问题的地方时,通过使用监视点的条件表达式,可以非常方便地找出问题代码:
watch i > 999
一旦i > 999,程序就会被中断,GDB指出改变条件的代码。
版权声明
本文出自 Lesca 技术宅,转载时请注明出处及相应链接。
本文永久链接: https://www.lesca.cn/archives/gdb-breakpoints-command-list-watchpoint.html