Stopping and Continuing

5.1 断点 观察点 和 检查点
可以设置一个断点在共享库。在HP-uX系统里:你必须等可执行文件跑起来后加载共享库。
watchpoint 也称数据断点 表达式的值改变了 程序停下来。
catchpoint 也称事件断点 当某种事件发生的时候 程序停下来
不管是breakpoint 还是watchpoint 还是catchpoint 都有一个唯一的数值表示。 如果是一个范围用- 连接。

5.1.1设置断点
break location: location可以是函数名 行号 指令的地址
break: 不带参数的break 在当前帧 的下一条语句设置一个断点
break … if cond 在 条件cond这里设置一个断点。 当该条件为true时候 程序停止
tbreak args 设置一个一次性断点 断点只执行一次 然后被删除
hbreak args 设置一个硬件断点 硬件断点的数目是有限制的 但是要受硬件支持
thbreak args 设置一个一次性的硬件断点
rbreak regex 设置一个正则表达式的断点 eg rbreak . 设置所有函数的断点
rbreak file:regex 设置一个文件内所有正则表达式匹配的断点。

info breakpoints[n…]
info break [n…] 打印所有木有被删除的断点,观察点 和 catchpoints
下边的几列会被打印:
类型: 断点 观察点 和 catchpoint
处理状态:该断点是否禁用 删除或者 命中
是否启用:y 启用 n 禁用
地址:断点在内存还是在程序,对于一个悬挂的断点 这一列是,直到内存加
载库文件。 这个断点匹配多个地址
描述:断点在程序 ,作为文件和行。对于一个悬挂的断点 原始传的断点命令将在这里
显示直到共享库被加载进来

一个断点可以对应的多处源代码的情况如下:
1.多个函数有相同的名字
2.C++构造函数 GCC编译器根据不同的情况产生不同的函数体
3.C++ 模板
4.内联函数

一个断点对应多个源代码的情况显示如下:
Num Type Disp Enb Address What
1 breakpoint keep y
stop only if i==1
breakpoint already hit 1 time
1.1 y 0x080486a2 in void foo() at t.cc:8
1.2 y 0x080486ca in void foo() at t.cc:8

每个位置都能独立的启用或禁用通过 enabled or disabled + breakpoint-number.location-number 例如上边的1.1 但是不能删除 1.1这种类型的断点,只能删除1 整个断点列表删除 disable 或者 enable 1 ,会影响1.1 1.2这些

set breakpoint pending auto 当GDB不能发现断点的位置 , 它询问你是否要建一个挂起的断点
set breakpoint pending on
set breakpoint pending off
show breakpoint pending

对于一些目标 GDB自动转换是硬件断点还是软件断点应该使用。这取决于断点地址是只读还是读写。这个转换在break , next fnish命令的时候。 但是对于hbreak GDB 总是使用硬件断点。 可以通过下列选项来控制这种自动行为:
set breakpoint auto-hw on 默认的行为 当GDB设置了一个断点 它会尝试使用内存map来决定是否要设置一个软件断点还是硬件断点

set breakpoint auto-hw off GDB 不要自动选择断点类型。
加入目标提供memor map , GDB 将提示在一个只读的地址 设置软件断点。

GDB实现断点通常是用一段特殊的指令取代程序的代码。在resume 的时候换, 在stop的时候 又换回来 这个过程自动完成。但是在慢速远程的目标上,这个替换过程可能会降低性能,这种行为受以下的命令控制:
set breakpoint always-inserted off
所有的断点包括用户新加入进去的 在程序resume的时候插入替换代码,所有的断点替换代码在程序停的时候移除
set breakpoint always-inserted on
实时的替换所有断点代码,而不是 resume时候, 当断点被移除的时候 断点替换代码被移除

set breakpoint condition-evaluatin host
set breakpoint condition-evaluation target
set breakpoint condition-evaluation auto

GDB 为了特殊的目的也会设置一些断点,这些断点的ID是负数 从-1开始 info breakpoints看不到, maint info breakpoints可以看到

5.1.2设置观察点(数据断点)
根据系统平台不同,watchpoint 可以实现成软断点和硬断点。软断点要被硬断点速度慢。

watch [-l|-location] expr [thread threadnum][mask maskvalue]
rwatch[-l|-location] expr [thread theadnum][mask maskvalue] 当表达式被读
awatch[-l|-location] expr [thread theadnum][mask maskvalue] 当表达式被写
info watchpoints [n…]

软断点速度慢,在下一条执行时,才能发现数据变了 硬断点速度快,当条指令就能发现
set can-use-hw-watchpoints: 是否使用硬断点
show can-use-hw-watchpoints: 显示上边选项的状态
awatch rwatch命令只能设置为硬断点。
硬件断点可能受机器字宽的影响。 例如一个整型长4,但是你试图在一个8Byte的长度上设置断点,这部分区域将会被分成独立的硬件断点。
交互的用print 或call 任何断点都会变成inactive 止到GDB到达另外一种类型的断点或 完成调用

当程序跑出局部的范围,局部范围内的函数或者表达式上的watchpoint会被删除。
警告:软件断点只看当前线程能改变的值 硬件断点 所有线程如果改变了当前值都有效。

5.1.3 设置事件断点
catch event event可以是如下值 当发生如下情况时,将被设断点
throw 抛出C++异常
catch 接受C++异常
exception 是指定的异常将触发断点, 不是指定的异常 程序将终止
如果指定的异常和系统的异常同名,必须给全路径
exception unhandled 一个异常产生但是木有被程序处理
assert
exec
syscall
syscall[name|number]… 假如木偶参数指定,任何system calls将被捕捉。
可以用补全功能补全name.GDB有一个库维持着 name和number的对应关系
fork
vfork
load[regexp]
unload[regexp]当加载或卸载名字匹配正则的静态库时候 设置断点
tcatch event 一次性catch
建议是在异常触发的时候 就设断点, 在异常处理的函数里 设断点不是一个好方法(上边设置的情况) ,通常设置函数断点 例如C++ 在__raise_exception处设置函数断点

5.1.4删除断点
GDB自动忽略 C 继续执行下一条代码上的断点
clear:清除当前栈帧上将要执行代码上的任何断点
clear location:清除指定位置上的断点
clear function
clear filename:function
clear linenum
clear filename:linenum
delete[breakpoints][range…] 如果木有参数 将清除所有断点,在这个操作之前GDB一般都会确认

5.1.5 禁用断点
disable [breakpoints][range…]
enable [breakpoints][range…]
enable [breakpoints] count count range
enable [breakpoints] delete range…

5.1.6 Break Condition
condition bnum expression 在bnum处设置expression
condition bnum 取消bnum处设置的expression
ignore bnum count 忽略count次break

5.1.7 断点命令
commands [range…]
…command-list…
end 为指定的断点设置一序列命令。当断点停掉程序时,这些命令将会出现在要调试程序的下一行
commands end(就是中间木有command list) 清出这个断点上的所有命令
如果不指定参数,commands设置的是最近一个断点。
RET不重复GDB command 命令。 如果command-list里边有 continue step命令,则断点继续执行而忽略command-list剩下的命令

command-list的第一条命令如果是silent,则会禁止断点信息输出。你都不会察觉已经有断点发生过,不过可以显示的调用print等。有两种用途 1.silent 后跟 print 来显示特定的值 2.slient后跟set ,断点到达时候显示的更改变量的值。

5.1.8动态的printf
dprintf 可以不编译你的程序,动态的产生指定格式化的信息
dprintf location,tmplate,expression[,expression…]无论什么时候到达location, 用template格式化
expression的值 并打印它们。多个expression用逗号隔开
set dprintf-style style
style 可以是以下几种:
gdb 处理输出用GDB printf命令
call 处理输出通过调用一个function在程序里
agent 远程debuging agent处理

set dprintf-function function
设置 style=call,调用的函数,默认是printf
set dprintf-channel channel 设置dprintf 的通道。假如不是空值,作为第一个参数传递给dprintf-function的。如果是空值 则dprintf format 字符串将作为第一个参数值
set dprintf-style call
set dprintf-function fprintf
set dprintf-channel mylog
dprintf 25 ,”at line 25,glob=%d\n”,glob 其作用是fprintf打印输出到mylog里边
dprintf可以用info命令来查到

set disconnected-dprintf on
set disconnected-dprintf off 假如dprintf-style是agent dprintf决定 GDB从target断开 是继续执行还是
停止
show disconnected-dprintf off 显示当前 disconnected dprintf的选择

5.1.9怎样把断点存在文件里边
save breakpoints [filename] 可以把当前的断点信息保存在一个文件里边 用于下一次的调试 下一次调试勊
用source命令来加载。 一些局部变量在重新加载的时候可能会失败

5.1.10 static probe points

5.1.11不能插入断点
如果出现上述信息 cannot insert breakpoints , 你需要做的就是 disable或者delete 一些断点.

5.1.12 Breakpoint address adjusted…
由于平台的原因 打呢断点可能会被调整 对调试木有影响

5.2 Continuing and stepping
continue [ignore-count]
c [ignore-count]
fg [ignore-count] ignore-count表示多少次以后继续

step: 步入。假如一个函数里木有debug information ,stp会一直跑到有debug information的地方才会停
如果要步入到一个木有调试信息的function里边,用stepi
step count: count 次step
next [count]:不跟进函数内部
set step-mode
set step-mode on 即使木有调试信息也跟进函数
set step-mode off 木有调试信息就不跟进函数了 默认选择
show step-mode
finish: 结束当前函数,并打印返回值
until
u : 运行到当前行为止,假如程序退出但钱函数栈帧,until就会停止了
until location
u location 止到指定的location到达,程序停止
advance location:止到指定的location到达,程序停止,如果程序退出当前的函数栈帧,advance也会停
和until 的区别:advance 不跳过递归的函数调用,目标位置的栈帧和当前的函数栈帧
不能是同一个

stepi
stepi arg
si 单步执行机器码,遇到函数步入

nexti
nexti arg
ni 单步执行机器码,遇到函数不步入

5.3 跳过函数和文件
int func()
{
foo(boring());
bar(boring());
}

如果用setp的话 会步入到boring里边,要进入到foo 而不进入到boring里边,skip命令
skip [linespec]
skip function [linespec] 跳过含有linespec行的函数 ,假如木有linespec,则跳过当前你正在调试的函数
skip file [filename] 当跑完这条命令 任何在filename里边的function都会被跳过。如果木有指定filename任何在当前file里边的函数都将被跳过
info skip [range] 打印skip的详细信息 包括以下几列:
Identifier 一个整型的ID
Type 跳过的类型 function 或者file
Enabled or disabled
address:如果你指定的函数还木有被加载 这一列里是 如果一个共享库被加载了,这里将显示函数的
地址
what:如果是文件 这里包含的被skip的文件名 如果是函数 这一列包含的函数名和它的行号在文件里边的
skip delete [range] 假如range木有被指定,删除所有的skips
skip enable [range] 假如range木偶被指定,启用所有的skips
skip disabled [range]假如range木有被指定,禁用所有的skips

5.4 信号
info handle 打印信号的种类 和GDB怎么处理这些信号
info signals sig 只打印 sig指定的相关信号 info handle 是 info signals的别名
handle signal [keywords…]
nostop : 当信号发生时候,GDB不停止程序 只是告诉 这个信号发生过
stop: 当信号发生时 GDB停止程序 并且打印消息
print: 当信号发生时,GDB打印一条消息
noprint: GDB忽略信号的发生 也就意味着 nostop
pass
noignore GDB允许程序接受signal.

nopass
ignore GDB不传递信号给程序

可以用 ptype $_siginfo 命令来打印siginfo_t 类型

5.5 停止和开始多线程程序
有两个选项 all-stop 当一个线程断点时,其他所有线程停止, non-stop mode 当个线程断点时,其他线程继续运行

5.5.1 All-Stop Mode
set scheduler-locking mode 假如mode是off ,其他线程可以随时跑起来 假如是on 当前inferior被resumed,只有当前进程可以跑。除非其他线程遇到了断点,GDB 才会把控制权放在其他线程上
show scheduler-locking 显示当前的设置

set schedule-multiple 如果是on 允许所有的被调试的所有进程的所有线程可以同时执行
如果是off 只有当前进程的所有线程可以同时执行 注意 可以结合上边的标记
show schedule-multiple 显示参数

5.5.2 Non-Stop Mode
在这种模式下 只有当前的被调试的线程会停止,其他线程继续运行。continue ,step默认只被运用在当前线程。而不是像all-stop模式中 运用到所有线程。
set non-stop on
set non-stop off
show noe-stop
这些选项只有在开始调试程序之前设置了才有效,如果平台不支持也无效。

在non-stop模式总,所有的命令都是运用在当前线程。 默认 continue只会开始一个线程,为了继续所有的线程, 必须用continue -a命令

当程序跑在后台的时候 interrupt停止执行 Ctrl-c 终止前台程序的执行。在all-stop模式 停止所有进程
在 non-stop模式 只是停止当前线程,在这种模式下 为了停止所有的进程 ,则要用interrupt -a
注意:不是所有命令都支持-a选项。

5.5.3 后台执行
GDB执行命令分两类: 1. normal foreground 2. background
在开启background之前 需要开启 asynchronous模式
可以用下边的命令来完成:
set target-async on
set target-async off
show target-async

开启以上模式后就可以运行后台命令了,在命令后边加个& 变成后台运行
支持&符号的命令有以下几个:
run
attach
step
stepi
next
nexti
finish
continue
finish
until

5.5.4 线程断点
break linespec thread threadno
break linespec thread threadno if …
假如木有thread treadno条件,这个断点就是对所有的线程有效

5.5.5 中断系统调用
当你中断线程的时候,系统调用在这个期间可能会返回。例如:sleep(10)
这是一个需要注意的地方

5.5.6 观察者模式
所谓观察者模式 就是不让GDB干预程序的某些行为的运行,可以通过选项指定
set observer on
set observer off
show observer
禁用以下所有选项 ,包括non-stop模式
set may-write-registers on
set may-write-registers off 是否让GDB修改寄存器的值 默认值是允许
show may-write-registers

set may-write-memory on
set may-write-memory off 是否让GDB修改内存里边的东西 默认值是允许
show may-write-memory

set may-insert-breakpoints on
set may-insert-breakpoints off 是否允许插入断点,默认是允许
show may-insert-breakpoints

set may-insert-tracepoints on
set may-insert-tracepoints off
show may-insert-tracepoints 是否允许插入tracepoint,只能控制non-fast tracepoints,fast-tracepoints受may-insert-fast-tracepoints的控制

set may-insert-fast-tracepoints on
set may-insert-fast-tracepoints off 允许是否插入fast-tracepoint
show may-insert-fast-tracepoints

set may-interrupt on
set may-interrupt off 当off的时候 interrupt, Ctrl-c都不能结束程序的执行 默认值是 on
show may-interrupt

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据