在机器级别使用 dbx 进行调试
可使用 dbx 调试程序在汇编语言级别检查程序。 可显示并修改内存地址、显示汇编指令、单步执行指令、设置断点并跟踪位于内存地址事件,以及显示寄存器。
在接下来的命令和示例中,地址即得出内存地址的表达式。 The most common forms of addresses are integers and expressions that take the address of an identifier with the & (ampersand) operator. 还可将地址指定为机器级别命令中引在括号中的表达式。 地址可由其他地址、运算符 +(加号)、-(减号)以及间接地址(一元 *)组成。
以下部分包含有关在机器级别使用 dbx 程序进行调试的更多信息。
使用机器寄存器
使用 寄存器 子命令来查看机器寄存器的值。 将寄存器分为 3 个组:通用、浮点以及系统控制。
通用寄存器
通用寄存器由 $rNumber 表示,其中,Number 代表寄存器号。
注: 寄存器值可以设置为十六进制值0xdeadbeef. 这是在进程初始化时分配给所有通用寄存器的初始化值。
浮点寄存器
浮点寄存器由 $rNumber 表示,其中,Number 代表寄存器号。 在缺省情况下,不显示浮点寄存器。 可使用 unset $novregs 复位 $novregs 调试程序变量以使浮点寄存器能够显示。 使用打印和赋值子命令时,也可以按类型引用浮点数寄存器。$frNumber默认为 double 类型。$frNumberh引用_Decimal32类型的浮点数寄存器,$frNumberd引用_Decimal64类型的浮点数寄存器。 以下是不同类型的浮点寄存器的示例:
(dbx) print $fr0
1.10000002
(dbx) print $fr0h
1.100001
(dbx) print $fr0d
1.10000062
(dbx) assign $fr0 = 9.876
(dbx) assign $fr0h = 9.876df
(dbx) assign $fr0d = 9.876dd
向量寄存器
向量寄存器由 $vrNumber 表示,其中,Number 代表寄存器号。 缺省情况下,不显示向量寄存器,并且它们仅存在于支持向量处理单元的处理器上。
您可以取消设置 $novregs 调试程序变量,以使用 unset $novregs启用向量寄存器显示。 当将向量寄存器与 print 和 assign 子命令一起使用时,还可以按类型引用向量寄存器。 $vrNumber 缺省为向量类型 int。 $vrNumberf 将向量引用为类型 float。 $vrNumbers 将向量作为短类型引用。 $vrNumberc 以 char 类型引用向量。
以下是不同类型的向量寄存器的示例:
(dbx) print $vr20
((1066192077, 1074161254, 1078355558, 1082340147))
(dbx) print $vr20f
((1.10000002, 2.0999999, 3.0999999, 4.0999999))
(dbx) print $vr20s
((16268, 52429, 16390, 26214, 16454, 26214, 16515, 13107))
(dbx) assign $vr20f[3] = 9.876
(dbx) print $vr20f ((1.10000002, 2.0999999, 3.0999999,
9.8760004))
系统控制寄存器
受支持的系统控制寄存器由以下内容表示:
- 指令地址寄存器:$iar 或 $pc
- 条件状态寄存器:$cr
- 乘数商数寄存器:$mq
- 机器状态寄存器:$msr
- 链接寄存器:$link
- 计数寄存器:$ctr
- 定点异常寄存器:$xer
- 事务标识寄存器:$tid
- 浮点状态寄存器:$fpscr
检查内存地址
使用以下命令格式从第一个地址开始显示内存的内容直至到达第二个地址时或直至显示 Count 变量指定的项数时停止显示。 Mode 指定如何显示内存。
- 地址, 地址 / [方式] [> 文件]
- Address / [Count] [Mode] [> File]
如果省略了 Mode 变量,那么重新使用先前指定的方式。 初始方式为 X。 支持以下方式:
- b
- 打印八进制的字节。
- c
- 按字符打印一个字节。
- D
- 按十进制打印一个长字。
- d
- 按十进制打印一个短字。
- Df
- 打印双精度十进制浮点数。
- DDf
- 显示四倍精度十进制浮点数。
- f
- 显示单精度浮点数。
- g
- 显示双精度浮点数。
- Hf
- 打印单精度十进制浮点数。
- h
- 以十六进制打印一个字节。
- i
- 打印机器指令。
- lld
- 打印带符号的 8 字节十进制数。
- llo
- 打印无符号的 8 字节八进制数。
- llu
- 打印无符号的 8 字节十进制数。
- llx
- 打印无符号的 8 字节十六进制数。
- O
- 按八进制打印一个长字。
- o
- 以八进制显示短整型字。
- q
- 打印一个扩展精度的浮点数。
- s
- 打印一个空字节结尾的字符串。
- X
- 按十六进制打印一个长字。
- x
- 按十六进制打印一个短字。
在以下示例中,可将括号中的表达式作为地址使用:
(dbx) print &x
0x3fffe460
(dbx) &x/X
3fffe460: 31323300
(dbx) &x,&x+12/x
3fffe460: 3132 3300 7879 7a5a 5958 5756 003d 0032
(dbx) ($pc)/2i
100002cc (sub) 7c0802a6 mflr r0
100002d0 (sub + 0x4) bfc1fff8 stm r30,-8(r1)在机器级别运行程序
用于在机器级别调试程序的命令与在符号级别调试程序的命令相似。 stopi 子命令在达到地址,条件为 true 或变量更改时停止机器。 tracei 子命令类似于符号跟踪命令。 stepi 子命令执行一个或指定的 Number 机器指令。
如果此时执行了另一个 stepi 子命令,那么将在标识为过程入口点的地址 0x10000618处停止printf。如果您不打算在此地址停止,那么可以使用 return 子命令在下一个指令中继续执行。sub地址 0x100002e0。 此时,nexti 子命令将自动继续执行到 0x10000428。
如果程序含有多个线程,那么正在运行的线程的符号线程名称将会在程序停止时显示。 例如:
stopped in sub at 0x100002d4 ($t4)
10000424 (sub+0x4) 480001f5 bl 0x10000618 (printf)调试 fdpr 重新排序的可执行文件
您可以在指令级调试使用fdpr(反馈指导程序重组, AIX®性能工具箱的一部分)重新排序的程序。 如果使用优化选项 -R0 或 -R2,那么提供附加信息以使 dbx 将大多数重新排序的指令地址映射到原始可执行文件中的相应地址,如下所示:
0xRRRRRRRR = fdpr[0xYYYYYYYY]在此示例中, 0xRRRRRRRR是重新排序的地址, 0xYYYYYYYY是原始地址。 此外, dbx 使用原始指令区域中的回溯条目来查找 stopped in消息, func 子命令和 traceback。
(dbx) stepi
stopped in proc_d at 0x1000061c = fdpr[0x10000278]
0x1000061c (???) 9421ffc0 stwu r1,-64(r1)
(dbx)在前面的示例中, dbx 指示程序在 proc_d子例程的地址 0x1000061c在原先位于地址的重排序文本部分中 0x10000278. 有关 fdpr的更多信息,请参阅 fdpr 命令。
显示汇编指令
dbx 命令的 listi 子命令显示源文件的指定指令集。 dbx 程序以缺省方式列示它在其上运行的体系结构的指令。 可使用 dbx 命令的 set 子命令的 $instructionset 和 $mnemonics 变量覆盖该缺省方式。
有关显示指令或反汇编指令的更多信息,请参阅 dbx 命令的 listi 子命令。 有关覆盖该缺省方式的更多信息,请参阅 dbx 命令的 set 子命令的 $instructionset 和 $mnemonics 变量。