Zxdb 可以对简单的 C、C++ 和 Rust 表达式进行求值并输出值。在 zxdb 中,最常见的表达式求值用例是使用 print 动词。表达式还可用于将内存位置作为参数的命令,例如 stack 或 mem-read。
在对表达式求值时,您需要一个堆栈帧,而堆栈帧又需要一个具有已暂停线程的进程。如果进程当前正在运行,您可以使用 pause 动词暂停线程。
您可以使用 print 命令显示当前堆栈帧中变量的当前值:
例如,如需查看变量 i 的值,请运行以下命令:
print i
34
您还可以在另一个堆栈帧的上下文中对表达式求值,而无需切换到该帧。
例如,如需查看堆栈帧 2 中 argv[0] 的值,请运行以下命令:
frame 2 print argv[0]
"/bin/cowsay"
使用表达式输出
print 命令接受以下参数:
--max-array=<number>:指定要输出的最大数组大小。默认情况下,此值为 256。指定较大的值会减慢表达式求值速度。--raw或-r:绕过美观输出器,显示原始类型信息。--types或-t:强制开启类型打印。系统会明确显示输出的每个值的类型。表示-v。--verbose或-v:请勿省略类型名称。显示引用地址和指针类型。
如需编写以连字符开头的表达式,请使用 -- 标记实参的结尾。-- 后面的连字符会被视为表达式的一部分:
print -- -i
数字格式选项
print 命令接受以下选项,以强制数值为特定类型:
-b:二进制-c:字符-d:有符号十进制数-u:无符号十进制数-x:无符号十六进制
特殊变量
在 zxdb 中使用变量时,您可能会遇到无法在当前语言中解析的标识符名称。编译器生成的符号通常就是这种情况。请务必将此类字符串括在 $(<symbols>) 中。
转义内容中的括号只要成对出现,就可以是字面量,否则,请在括号前面加上反斜杠进行转义。如需在表达式中使用字面意义的反斜杠,请使用两个反斜杠。
以下都是有效示例:
$(something with spaces)$({{impl}})$(some_closure(data))$(line\)noise\\)
此外,zxdb 还支持:
CPU 寄存器
您可以使用 $reg(register name) 语法引用 CPU 寄存器。例如,如需显示 ARM 寄存器 v3,请运行以下命令:
print $reg(v3)
0x573a420f128
只要当前作用域中没有同名变量,CPU 寄存器也可以不转义使用。寄存器也可以像任何其他变量一样在更复杂的表达式中使用:
print -x rax + rbx
0x2108aa0032a
在支持可伸缩矢量扩展 (SVE) 的 ARM64 目标上,您还可以在表达式中引用 SVE 寄存器(z0-z31、p0-p15、ffr 和 vg)。
向量寄存器
根据 vector-format 的设置,矢量寄存器可以被视为数组。
print ymm1
{3.141593, 1.0, 0, 0}
[zxdb] print ymm[0] * 2
6.28319
列出向量寄存器
您可以使用 regs 列出矢量寄存器。
例如,如需列出所有向量寄存器,请运行以下命令:
regs --vector
(Use "print $registername" to show a single one, or
"print $registername = newvalue" to set.)
Vector Registers
mxcsr 0x1fa0 = 8096
Name [3] [2] [1] [0]
ymm0 0 0 -3.72066e-103 -3.72066e-103
ymm1 0 0 3.79837e-312 2.63127e-312
ymm2 0 0 0 -3.72066e-103
ymm3 0 0 1.26218e-311 1.26218e-311
ymm4 0 0 1.26218e-311 1.26218e-311
ymm5 0 0 1.26218e-311 1.26218e-311
ymm6 0 0 5.96337e-321 5.87938e-321
ymm7 0 0 2.56125e-311 2.4891e-311
ymm8 0 0 0 0
ymm9 0 0 0 0
ymm10 0 0 0 0
ymm11 0 0 0 0
ymm12 0 0 0 0
ymm13 0 0 0 0
ymm14 0 0 0 0
ymm15 0 0 0 0
(Use "get/set vector-format" to control vector register interpretation.
Currently showing vectors of "double".)
使用 display
在单步调试函数时,如果每次程序停止时都能自动输出一个或多个表达式,会非常有用。display 命令会将给定表达式添加到此列表中:
display status
Added to display for every stop: status
[zxdb] next
🛑 main(…) • main.cc:48
[code dump]
status = 5;
使用 locals
locals 命令会显示当前堆栈帧中的所有局部变量。它接受与 print 相同的实参(请参阅使用表达式输出):
locals
argc = 1
argv = (const char* const*) 0x59999ec02dc0