调试器 Debugger
Forge 附带一个交互式调试器 Debugger。
调试器 Debugger 可在 forge debug
和 forge 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
标志指定要调试的合约。
调试器布局
导航
当调试器 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: 显示帮助
Navigating calls
- 0-9 + k:向后移动数次(或者用鼠标向上滚动)
- 0-9 + j:向前走几步(或者用鼠标向下滚动)
- g: 移动到事务的开头
- G:移至事务末尾
- c:移至上一个调用类型指令(即
CALL
、STATICCALL
、[DELEGATECALL
][op- delegatecall] 和CALLCODE
)。 - C: 移动到下一个调用类型指令
- a: 移动到上一个
JUMP
或JUMPI
指令 - s: 移动到下一个
JUMPDEST
指令 - ' + a-z: 移动到由
vm.breakpoint
作弊码设置的<char>
断点
Navigating memory
- Ctrl + j:向下滚动内存视图
- Ctrl + k:向上滚动内存视图
- m: 将内存显示为 UTF8
Navigating the stack
- J:向下滚动堆栈视图
- K:向上滚动堆栈视图
- t: 在堆栈上显示标签以查看当前操作将消耗哪些项