Foundry 打断点进行调试

  • Alan
  • 发布于 16小时前
  • 阅读 41

Foundry在测试环境中设置断点、逐步执行代码,并检查EVM状态(如栈、内存、调用等)

Foundry 是基于 Rust 的以太坊开发工具包,主要用于 Solidity 智能合约的测试、部署和调试。它内置了一个交互式调试器(通过 Forge),支持在测试环境中设置断点、逐步执行代码,并检查 EVM 状态(如栈、内存、调用等)。断点主要通过 cheatcode vm.breakpoint() 实现,而不是图形化 IDE 中的点击设置。下面是详细步骤

前提条件

  • 安装 Foundry:运行 curl -L https\://foundry.paradigm.xyz | bash,然后 foundryup 更新到最新版本。
  • 项目结构:使用 forge init 创建项目,编写 Solidity 合约和测试文件(通常在 test/ 目录下,使用 Forge Std 测试框架)。

步骤:使用内置 Forge 调试器设置断点和调试Foundry 的调试器是终端-based 的,支持在测试失败或特定点暂停执行。断点通过在代码中插入 cheatcode 来设置,然后在调试界面中使用快捷键导航。

  1. 在代码中设置断点:

    • 在你的 Solidity 测试或合约代码中,导入 Forge Std 的 Test 和 Vm 接口(import {Test, Vm} from "forge-std/Test.sol";)。

    • 在需要暂停的位置插入 vm.breakpoint("\<char>");,其中 \<char> 是小写字母(a-z),作为断点标签。例如:

      solidity

      // 在 test/MyTest.t.sol 中
      import {Test, Vm} from "forge-std/Test.sol";
      
      contract MyTest is Test {
       function testExample() public {
           // 一些代码...
           vm.breakpoint("a");  // 设置标签 "a" 的断点
           // 更多代码...
           vm.breakpoint("b", false);  // 可选:false 参数用于移除断点
       }
      }
      • 注意:如果多个断点使用相同标签,只考虑执行路径中最后遇到的一个。
  2. 启动调试器:

    • 运行测试并启用调试模式:forge test --debug --match-test "\<regex>",其中 \<regex> 是测试函数的正则表达式(例如 testExample)。

      • 示例:forge test --debug --match-test "testExample"
      • 这会编译代码、运行测试,并在遇到断点或测试失败时打开交互式调试器。
      • 对于模糊测试(fuzz tests),调试器会在第一个失败场景或最后一个成功场景打开。
    • 如果是脚本调试,使用 forge script --debug \<script_path>。

  3. 调试界面和导航:

    • 调试器打开后,终端分为四个象限:

      • 左上:当前操作码(opcode),突出显示当前指令、账户地址、程序计数器(PC)和 gas 使用。
      • 右上:栈(stack)视图,大小和内容。
      • 左下:源代码视图。
      • 右下:内存(memory)视图。
    • 颜色提示:

      • 内存:红色(即将写入)、绿色(上一个写入)、青色(当前读取)。
      • 栈:青色(当前读取或弹出)。
    • 导航到断点:

      • 按 '\<char>(例如 'a)跳转到对应断点的执行位置。
    • 其他快捷键:

      • 步进:0-9 + j(向前步进指定步数,或向下滚动);0-9 + k(向后步进,或向上滚动)。
      • 跳转:g(到交易开头);G(到交易结尾)。
      • 调用相关:c(上一个调用指令,如 CALL);C(下一个调用)。
      • 跳转指令:a(上一个 JUMP/JUMPI);s(下一个 JUMPDEST)。
      • 内存/栈滚动:Ctrl + j/k(内存下/上);J/K(栈下/上);m(内存显示为 UTF8);t(栈显示标签)。
      • 其他:q(退出);h(帮助)。
    • 在暂停时,你可以检查变量、栈、内存和调用栈,以诊断问题。

  4. 高级用法:

    • 增加详细度:使用 forge test -vvvv 获取更多日志(trace),结合调试器使用。

    • 操作码级调试:调试器支持逐 opcode 步进,适合低级分析。

      updraft.cyfrin.io

    • 测试失败处理:调试器会报告最后一个失败的断言(从 DSTest 或 cheatcodes)。

    • 如果需要图形化界面,考虑 VS Code 扩展如 Simbolik(Runtime Verification 出品),它支持在 Foundry 项目中逐行步进、设置断点和变量检查。

      marketplace.visualstudio.com

      安装步骤:搜索 VS Code Marketplace 中的 "Simbolik",安装后在 Foundry 项目中启用 Solidity 调试配置(可能需要配置 launch.json)。

注意事项

  • Foundry 调试主要针对测试环境(本地模拟),不直接支持已部署合约的实时调试(为此使用 Tenderly 或 Etherscan)。
  • 确保你的测试使用 forge-std 库来访问 vm cheatcodes。
  • 如果断点未触发,检查是否正确匹配了测试函数,或代码路径是否执行到断点。
  • 对于复杂项目,结合单元测试和日志(console.log)来辅助。
点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Alan
Alan
0x9cAD...0097
区块链BTC、ETH、BNB