调试器 Debugger

Forge 附带一个交互式调试器 Debugger。

调试器 Debugger 可在 forge debugforge test 上访问。

使用 forge test:

$ forge test --debug $FUNC

其中 $FUNC 是你要调试的函数的签名。 例如:

$ forge test --debug "testSomething()"

如果你有多个具有相同函数名称的合约,则需要使用 --match-path--match-contract 将匹配函数限制为只有一种情况。

如果匹配测试是模糊测试,调试器 Debugger 将打开第一个失败的模糊场景,或者最后一个成功的场景,以先到者为准。

使用 forge test

$ forge debug --debug $FILE --sig $FUNC

其中 $FILE 是你要调试的合约的路径,$FUNC 是你要调试的函数的签名。 例如:

$ forge debug --debug src/SomeContract.sol --sig "myFunc(uint256,string)" 123 "你好"

你还可以使用 --sig 而不是函数签名来指定原始调用数据。

如果你的源文件包含多个合约,请使用--target-contract标志指定要调试的合约。

调试器布局

An image of the debugger UI

导航

当调试器 Debugger 运行时,你会看到一个分为四个象限的终端:

  • Quadrant 1:调试会话中的操作码,当前操作码突出显示。 此外,还会显示当前账户地址、程序计数器和累计 Gas 用量
  • Quadrant 2:当前栈,以及栈的大小
  • Quadrant 3:源视图
  • Quadrant 4:EVM 的当前内存

在逐步执行代码时,你会注意到堆栈和内存中的单词有时会改变颜色。

对于内存:

  • Red words 即将被当前操作码写入
  • Green words 被之前的操作码写入
  • Cyan words 正在被当前操作码读取

对于堆栈,cyan words正在被当前操作码读取或弹出。

⚠️ 注意

在大多数测试框架中,第一个失败的测试断言是被报告的。 在 foundry 中,最后一个失败的测试断言(来自 DSTest 或 cheatcodes)将被报告。

导航

General

  • q: 退出 debugger
  • h: 显示帮助
  • 0-9 + k:向后移动数次(或者用鼠标向上滚动)
  • 0-9 + j:向前走几步(或者用鼠标向下滚动)
  • g: 移动到事务的开头
  • G:移至事务末尾
  • c:移至上一个调用类型指令(即 CALLSTATICCALL、[DELEGATECALL][op- delegatecall] 和 CALLCODE)。
  • C: 移动到下一个调用类型指令
  • a: 移动到上一个 JUMPJUMPI 指令
  • s: 移动到下一个 JUMPDEST 指令
  • ' + a-z: 移动到由 vm.breakpoint 作弊码设置的 <char> 断点
  • Ctrl + j:向下滚动内存视图
  • Ctrl + k:向上滚动内存视图
  • m: 将内存显示为 UTF8
  • J:向下滚动堆栈视图
  • K:向上滚动堆栈视图
  • t: 在堆栈上显示标签以查看当前操作将消耗哪些项