评估和输出 zxdb 中的表达式

Zxdb 可以对简单的 C、C++ 和 Rust 表达式求值。在 Zxdb 中,对表达式求值的最常见位置是使用 print 命令。表达式还可用于大多数将内存位置作为参数(例如 stackmem-read)的命令。

评估表达式需要堆栈帧,而堆栈帧需要一个线程处于已暂停状态的进程。如果该进程当前正在运行,请使用 pause 命令。

最基本的输出命令会显示当前堆栈帧中变量的当前值:

[zxdb] print i
34

还支持更复杂的表达式:

[zxdb] print &foo->bar[baz]
(const MyStruct*) 0x59f4e1268f70

通过将所需的堆栈帧指定为前缀,表达式可在其他堆栈帧的上下文中求值(请参阅交互模型):

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

语言

表达式求值从当前堆栈帧中获取表达式编程语言。如果当前帧的语言不同,Zxdb 默认使用 C++。

默认语言可通过 lauguage 设置替换,其可采用值 auto(使用当前帧的语言)、rustc++

[zxdb] set language rust

开关

print 命令接受这些开关。如需编写以连字符开头的表达式,请使用 -- 标记开关的结尾。以下连字符被视为表达式的一部分:

[zxdb] print -- -i
  • --max-array=<number>:指定要输出的最大数组大小。默认值为 256。 指定较大的值会减慢表达式评估速度,并使输出更难以读取,但默认值有时不够用。这也适用于字符串。

  • --raw-r:绕过美观输出程序并显示原始类型信息。

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

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

特殊变量

可以使用 $reg(register name) 语法引用 CPU 寄存器。例如,如需显示 ARM 寄存器 v3

[zxdb] print $reg(v3)
0x573a420f128

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

[zxdb] print rax + rbx

可以根据 vector-format 设置将向量寄存器视为数组。

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

[zxdb] print ymm[0] * 2
6.28319

有时,标识符的名称可能无法以当前语言解析。编译器生成的符号通常就属于这种情况。将此类字符串包含在“$(...)”中。只要经过平衡,转义内容内的圆括号可以是字面意义,否则,请在前面添加反斜杠对其进行转义。添加带有两个反斜杠的字面反斜杠:

  • $(something with spaces)
  • $({{impl}})
  • $(some_closure(data))
  • $(line\)noise\\)

设置变量

print 命令还可以更改数据,允许通过表达式设置变量。例如:

[zxdb] print done_flag = true
true
[zddb] print i = 56
56

其他数据显示命令

  • 内存部分介绍了内存显示命令。
  • assembly 部分介绍了寄存器显示命令。

locals 命令

locals 命令会显示当前堆栈帧中的所有局部变量。它接受的开关与 print 相同:

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

display 命令

单步调试某个函数时,在每次程序停止时自动输出一个或多个表达式会很有帮助。display 命令会向此列表中添加给定表达式:

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

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

    [code dump]

status = 5;