对表达式求值

Zxdb 可以从简单的 C、C++ 和 Rust 表达式求值和输出值。在 zxdb 中对表达式求值的最常见用例是使用 print 动词。表达式也可用于将内存位置作为参数的命令,例如 stackmem-read

对表达式求值时,您需要一个堆栈帧,而堆栈帧又需要一个具有已暂停线程的进程。如果进程当前正在运行,您可以使用 pause 动词来暂停线程。

您可以使用输出命令显示当前堆栈帧中变量的当前值:

例如,如需查看变量 i 的值,请使用以下代码:

[zxdb] print i
34

您还可以在另一个堆栈帧的上下文中对表达式求值,而无需切换到该帧。

例如,如需查看堆栈帧 2argv[0] 的值,请使用以下代码:

[zxdb] frame 2 print argv[0]
"/bin/cowsay"

print 命令接受以下参数:

  • --max-array=<number>:指定要输出的数组大小上限。默认为 256。指定较大的值会减慢表达式评估速度。

  • --raw-r:绕过美观打印机并显示原始类型信息。

  • --types-t:强制开启类型打印功能。系统会明确显示输出的每个值的类型。隐含了 -v

  • --verbose-v:请勿省略类型名称。显示引用地址和指针类型。

如需编写以连字符开头的表达式,请使用 -- 标记参数的结尾。-- 后面的连字符会被视为表达式的一部分:

[zxdb] 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,请运行以下命令:

[zxdb] print $reg(v3)
0x573a420f128

只要当前范围内没有任何变量具有相同的名称,CPU 寄存器也可以不转义。寄存器也与更复杂的表达式中的任何其他变量一样使用:

[zxdb] print -x rax + rbx
0x2108aa0032a

向量寄存器

根据 vector-format 的设置,矢量寄存器可被视为数组。

[zxdb] print ymm1
{3.141593, 1.0, 0, 0}

[zxdb] print ymm[0] * 2
6.28319

列出矢量寄存器

您可以使用 regs 列出矢量寄存器。

例如,要列出所有向量寄存器:

[zxdb] 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 命令可将给定表达式添加到此列表中:

[zxdb] display status
Added to display for every stop: status

[zxdb] next
🛑 main(…) • main.cc:48

    [code dump]

status = 5;

使用 locals

locals 命令会显示当前堆栈帧中的所有局部变量。它接受与 print 相同的参数(请参阅使用表达式进行打印):

[zxdb] locals
argc = 1
argv = (const char* const*) 0x59999ec02dc0