stop 命令、stopi 命令、when 命令、wheni 命令、trace 命令和 tracei 命令使用事件规范表示事件类型和参数。此格式由一个表示事件类型和可选参数的关键字组成。 对于所有三种命令,事件规范的含义通常相同。在附录 D 的命令说明中介绍了各种异常。
断点是操作的发生位置,程序在该位置停止执行。本节介绍了断点事件的事件规范。
in 事件规范的语法如下:
in function
函数已输入,即将执行第一行。序进程后的第一个可执行代码用作实际断点位置。这一行可能会初始化局部变量。如果是 C++ 构造函数,在执行了所有基类构造函数后,将停止执行。如果使用 –instr 修饰符,则它是即将执行的第一个函数指令。function 规范可以接受形式参数签名,以支持重载的函数名或模板实例规范。例如:
stop in mumble(int, float, struct Node *)
at 事件规范的语法如下:
at [filename:]line-number
指定行即将被执行。如果指定 filename,则将执行指定文件中的指定行。文件名可以是源文件名或对象文件名。尽管引号并非必需,但如果文件名中包含特殊字符,则引号必不可少。如果指定行在模板代码中,则会在该模板的所有实例上放置断点。
at address-expression
给定地址处的指令即将被执行。此事件仅可与 stopi 命令或 –instr 事件修饰符结合使用
infile 事件规范的语法如下:
infile filename
该事件在文件中定义的每个函数中放置断点。stop infile 命令循环访问与 funcs –f filename 命令相同的函数列表。
.h 文件中的方法定义、模板文件或 .h 文件中的纯 C 代码(如 regexp 命令使用的那种)可能会为文件提供函数定义,但这些定义会被排除。
如果指定的文件名是对象文件的名称(即,该文件名以 .o 结尾),则会在出现在该对象文件中的每个函数上放置断点。
stop infile list.h 命令不会在 list.h 文件中定义的所有方法实例中放置断点。请使用诸如 inclass 或 inmethod 之类的事件来执行此操作。
fix 命令可以删除文件中的函数或向文件中添加函数。stop infile 命令可在文件中的所有旧版本函数中,以及未来可能添加的任何函数中放置断点。
不会在 Fortran 文件的嵌套函数或子例程中放置断点。
您可以使用 clear 命令禁用 infile 事件创建的集合中的单个断点。
infunction 事件规范的语法如下:
infunction function
对于所有名为 function 的重载函数或其所有模板实例,此规范等效于 in function。
inmember 事件规范的语法如下:
inmember function
此规范是 inmethod 事件规范的别名。
inmethod 事件规范的语法如下:
inmethod function
此规范等效于 in function 或每个类命名为 function 的成员方法。
inclass 事件规范的语法如下:
inclass classname [-recurse | -norecurse]
对于所有属于 classname 成员、但并非任何 classname 基础的成员函数,此规范等效于 in function。–norecurse 为缺省值。如果指定 –recurse,则包括基类。
inobject 事件规范的语法如下:
inobject object-expression [-recurse | -norecurse]
已调用针对 object-expression 表示的地址中的特定对象所调用的成员函数。stop inobject ox 大致等效于以下内容,但与 inclass 不同,它包括 ox 的动态类型基础。–recurse 为缺省值。 如果指定 –norecurse,则不包括基类。
stop inclass dynamic_type(ox) -if this==ox
本节介绍了涉及访问或更改内存地址内容的事件的事件规范。
access 事件规范的语法如下:
access mode address-expression [,byte-size-expression]
访问了由 address-expression 指定的内存。
mode 指定内存访问模式。有效值为以下一个字母或全部字母:
已读取指定地址处的内存。
已写入内存。
已执行内存。
mode 还可以包含以下任一项:
访问后停止进程(缺省值)。
访问前停止进程。
在这两种情况下,程序计数器都将指向违例指令。“之前”和“之后”都具有副作用。
address-expression 是求值结果为地址的任何表达式。如果提供符号表达式,则会自动推导出要监视的区域大小。可以通过指定 byte-size-expression 覆盖它。也可以使用非符号、无类型地址表达式,在这种情况下,必须提供大小。例如:
stop access w 0x5678, sizeof(Complex)
access 命令具有限制,即:两个匹配区域不可重叠。
change 事件规范的语法如下:
change variable
variable 的值已更改。change 事件大致等效于:
when step { if [ $last_value !=$[variable]] then stop else last_value=$[variable] fi }
此事件使用单步执行来执行。要提高速度,可使用 access 事件。
即使未检测到更改,第一次检查 variable 时也会触发一个事件。这第一个事件是访问 variable 的初始值。以后检测到 variable 值的更改时会触发其他事件。
cond 事件规范的语法如下:
cond condition-expression
由 condition-expression 表示的条件的求值结果为 true。可以为 condition-expression 指定任何表达式,但其求值结果必须为整型。cond 事件大致等同于以下 stop 命令:
stop step -if conditional-expression
dlopen() 和 dlopen() 事件规范的语法如下:
dlopen [ lib-path ]
dlclose [ lib-path ]
成功调用 dlopen() 或 dlclose() 之后,会发生系统事件。调用 dlopen() 或调用 dlclose() 可能导致装入多个库。这些库列表始终可用于预定义的变量 $dllist 中。$dllist 中的第一个 Shell 字是 +(加号)或 -(减号),表示是在添加、还是删除库列表。
lib-path 是共享库的名称。如果指定该名称,则只在装入或卸载了给定库时才会发生事件。在这种情况下,$dlobj 包含库的名称。$dllist 仍然可用。
如果 lib-path 以 / 开头,则将执行完整字符串匹配。否则,将只比较路径的尾部。
如果未指定 lib-path,则只要出现 dl 活动,都会发生事件。在这种情况下,$dlobj 为空,但 $dllist 有效。
fault 事件规范的语法如下:
fault fault
遇到指定的故障时,会发生 fault 事件。 这些错误为体系结构相关式错误。dbx 的已知故障集在以下列表中列出,且在 proc(4) 手册页中已定义。
非法指令
特权指令
断点陷阱
跟踪陷阱(单步)
内存访问(如对齐)
内存边界(无效地址)
整数溢出
整数除以零
浮点异常
无法恢复的堆栈错误
可恢复的缺页
监视点陷阱
CPU 性能计数器溢出
上述错误摘自 /usr/include/sys/fault.h。fault 可以是上面所列错误中的任何一种(大小写、有无 FLT 前缀均可),也可以是实际的数字代码。
lwp_exit 事件规范的语法如下:
lwp_exit
退出 lwp 时,会发生 lwp_exit 事件。对于事件处理程序的持续时间,$lwp 包含退出的 LWP(轻量级进程)的 ID。
sig 事件规范的语法如下:
sig signal
信号第一次传递给调试的程序时,会发生 sig signal 事件。signal 既可以是十进制数,也可以是大写或小写的信号名称。 前缀是可选的。尽管 catch 命令可按如下所示实现,但此事件完全独立于 catch 命令和 ignore 命令:
function simple_catch { when sig $1 { stop; echo Stopped due to $sigstr $sig whereami } }
或者,您可以使用子代码指定信号。sig 事件规范的此选项的语法如下:
sig signal sub-code
首次将具有指定 sub-code 的指定信号传送到子进程时,会发生 sig signal sub-code 事件。对于信号,您可以十进制数、大写或小写字母的形式提供 sub-code。前缀是可选的。
sysin 事件规范的语法如下:
sysin code|name
刚启动了指定的系统调用,且进程已进入内核模式。
dbx 支持的系统调用概念,是指由进入内核(/usr/include/sys/syscall.h 中所枚举)中的陷阱所提供的概念。
此概念不同于系统调用的 ABI 概念。一些 ABI 系统调用在用户模式下得到部分实现,并且使用非 ABI 内核陷阱。但是,对于大多数普通系统调用(主要异常是信号处理),syscall.h 和 ABI 之间没有区别。
/usr/include/sys/syscall.h 中的内核系统调用陷阱列表是 Oracle Solaris OS 中的专用接口的一部分,它因版本而异。dbx 接受的陷阱名(代码)和陷阱编号列表包括 dbx 支持的任何 Oracle Solaris OS 版本支持的所有陷阱名(代码)和陷阱编号。dbx 支持的名称不可能与任何特定版本 Oracle Solaris OS 的名称完全匹配,且 syscall.h 中的某些名称可能不可用。任何陷阱编号(代码)均可为 dbx 接受,并可正常使用,但是,如果它与已知的系统调用陷阱不对应,系统会发出警告。
sysout 事件规范的语法如下:
sysout code|name
已完成指定的系统调用,进程即将返回到用户模式。
如果不使用参数,所有系统调用都会被跟踪。某些 dbx 功能(例如 modify 事件和运行时检查)会导致子进程为其自身目的执行系统调用,并且在被跟踪时显示出来。
本节介绍了有关于执行进度的事件的事件规范。
exit 事件规范的语法如下:
exit exitcode
next 事件类似于 step 事件,除了函数尚未步入以外。
returns 事件是当前已访问的函数返回点中的断点。 使用访问的函数是为了可以在提供大量 step up 命令后使用 returns 事件规范。returns 事件始终为 –temp,并且只有当存在活动进程时才能创建该事件。
returns 事件规范的语法如下:
returns function
每当给定的函数返回到其调用点时,都会执行 returns function 事件。 这不是临时事件。执行此操作时,并不提供返回值,但可以访问以下寄存器查找整型返回值:
基于 SPARC 的系统-$o0
基于 x86 的系统-$eax
基于 x64 的系统-$rax、$rdx
该事件大致等效于:
when in func { stop returns; }
执行源代码行的第一个指令时,会发生 step 事件。 例如,您可使用以下命令进行简单跟踪:
when step { echo $lineno: $line; }; cont
启用了 step 事件后,即指示 dbx 在下次使用 cont 命令时自动单步执行。
throw 事件的语法如下:
throw [type | –unhandled | –unexpected]
每当应用程序抛出任何未处理的或意外的异常时,均会发生 throw 事件。
如果异常类型使用 throw 事件指定,则只有该类型的异常才会导致 throw 事件的发生。
如果指定了 –unhandled 选项,则对于没有处理程序的情况,系统将抛出特殊异常类型,表明出现异常。
指定了 –unexpected 选项,该选项是一种特殊的异常类型,表示异常不符合抛出它的函数的异常规范。
当跟踪线程进入或退出屏障时,会涉及 omp_barrier 事件规范。您可以指定 type(它可以是 explicit 或 implicit)和 state(它可以是 enter、exit 或 all_entered)。缺省值为 explicit all_entered。
当跟踪线程进入或退出任务等待时,会涉及 omp_taskwait 事件规范。您可以指定 state(它可以是 enter 或 exit)。缺省值为 exit。
当跟踪线程进入或退出有序区域时,会涉及 omp_ordered 事件规范。您可以指定 state(它可以是 begin、enter 或 exit)。缺省值为 enter。
当跟踪线程进入重要区域时,会涉及 omp_critical 事件规范。
当跟踪线程进入或退出原子区域时,会涉及 omp_atomic 事件规范。您可以指定 state(它可以是 begin 或 exit)。缺省值为 begin。
当跟踪线程进入显式刷新区域时,会涉及 omp_flush 事件规范。
当跟踪线程进入或退出任务区域时,会涉及 omp_task 事件规范。您可以指定 state(它可以是 create、start 或 finish)。缺省值为 start。
当跟踪线程进入主要区域时,会涉及 omp_master 事件规范。
当跟踪线程进入单个区域时,会涉及 omp_single 事件规范。
attach 事件是 dbx 成功连接到进程。
detach 事件是 dbx 成功与所调试的程序分离。
lastrites 事件是所调试的进程即将过期,原因可能如下:
_exit(2) 系统调用已通过显式调用发生,或在 main() 返回时发生。
即将传送终止信号。
进程正由 kill 命令中止。
触发此事件时,通常(但并非总是)会有进程的最终状态,从而提供了检查进程状态的最后机会。在此事件后恢复执行会终止进程。
当 dbx 不再与调试进程关联时,会发生 proc_gone 事件。 预定义变量 $reason 可以是 signal、exit、kill 或 detach。
当新程序作为 follow exec 的结果装入时,会发生 prog_new 事件。
每当进程停止以便用户收到提示(尤其是为了响应 stop 处理程序)时,都会发生 stop 事件。 例如,以下命令是等效的:
display x when stop {print x;}
正在调试的进程正好已使用 exec() 执行时,会发生 sync 事件。在 a.out 中指定的所有内存均有效且存在,但预装入的共享库尚未装入。例如,尽管 printf 可供 dbx 使用,但尚未映射到内存中。
对此事件执行 stop 不起作用,但可以将 sync 事件与 when 命令一起使用。
如果正在调试的进程尚未处理共享库,则在 sync 或 attach 之后会发生 syncrtld 事件。 它在动态链接程序启动代码已经执行且所有预装入共享库的符号表都已装入之后、.init 段中的任何代码运行之前执行。
针对此事件执行 stop 不起作用,但可以将 syncrtld 事件与 when 命令一起使用。
创建线程或具有指定线程 ID 的线程时,会发生 thr_create 事件。 例如,在以下 stop 命令中,线程 ID t@1 是指执行创建线程,而线程 ID t@5 是指被创建线程。
stop thr_create t@5 -thread t@1
线程退出时,会发生 thr_exit 事件。 要捕获特定线程的退出,请使用 stop 命令的 -thread 选项,如下所示:
stop thr_exit -thread t@5
timer 事件的语法如下:
timer seconds
正在调试的程序已针对 seconds 运行时,会发生 timer 事件。 用于此事件的计时器与 collector 命令共享。精度为毫秒,因此,seconds 可以为浮点值(例如 0.001)。