Skip to content

UTXO_Compiler 调试器用户使用手册

本文档介绍 UTXO_Compiler 内置 CLI 调试器的使用方法,适用于合约源码(.ct)的交互式调试。


1. 概述

1.1 功能简介

  • UTXO_Compiler Debugger 在编译后的字节码上运行一台 BVM(字节码虚拟机)模拟器,支持:
    • 断点(按行、按函数)
    • 单步执行(进入、跳过、跳出函数)
    • 查看源码、字节码、栈、调用栈
    • 交易数据加载与查看(合约调试场景)

1.2 启动条件

  • 项目需在 启用调试器 的情况下构建(BUILD_DEBUGGER)。
  • 启动调试器会先对源文件进行隐式编译,再进入交互式 REPL。

2. 启动调试器

2.1 命令行

bash
./utxo_compiler <源文件.ct> --debug

可选参数(与正常编译一致):

选项说明
--debug启动交互式调试器(同时启用调试信息)
--allow-subscope-altstack / --asa允许在子作用域(if/else、私有函数)中使用 setAlt/setMain
-l <level> / --log-level <level>设置日志级别(如 debug、info、warning)

示例:

bash
./utxo_compiler contract.ct --debug
./utxo_compiler contract.ct --debug --asa

2.2 启动流程

  1. 编译:对 源文件.ct 进行编译,生成字节码与调试信息;若编译失败,会输出错误并退出。
  2. 函数与参数(可选):若调试信息中存在函数列表,会提示:
    • 选择要调试的函数:输入编号 1N 只调试该函数;直接回车则调试整个文件,并为所有公有函数依次输入参数。
    • 参数输入格式(每个参数可任选其一):
      • 整数:42-1000x1a(十六进制)
      • 十六进制字节:0x1234abcd
      • 字符串:"hello"(双引号包围)
      • 回车:使用该参数类型的默认值
  3. 进入 REPL:显示 “UTXO_Compiler Debugger v1.0” 及加载的源文件名,提示输入 help 查看命令。

3. 命令总览

命令不区分大小写;多数命令有简写。下表为速查。

类别命令(简写)说明
执行控制run / r开始/重新开始执行
reset重置虚拟机到初始状态
continue / c从暂停处继续执行
step / s单步进入
next / n单步跳过
finish / f跳出当前函数
pause暂停执行
断点break / b <行号|\函数名>设置行断点或函数断点
delete / d <ID>删除断点
disable <ID>禁用断点
enable <ID>启用断点
info breakpoints / info bp列出所有断点
查看list / l [行号]显示源码(默认当前行附近)
stack显示主栈与副栈(支持参数)
backtrace / bt显示调用栈
bytecode / bc [N]显示字节码(可选上下文条数 N)
交易settxfile <文件>从文件加载交易数据
showtx显示当前交易数据
其他help / h显示帮助
quit / q / exit退出调试器
clear清屏

4. 执行控制

4.1 run / r

  • 作用:开始执行或从当前状态重新执行(不会重置 VM)。
  • 说明:若之前已设置初始栈(如函数参数),会从当前 PC 继续;通常与 reset 配合实现“重新跑一遍”。

4.2 reset

  • 作用:将虚拟机重置到初始状态(PC、栈等恢复为进入 REPL 时状态)。
  • 说明:断点保留;之后可用 runstep/next 重新执行。
  • 注意reset 不会清除已设置的断点,也不会清除通过 settxfile 加载的交易数据。

4.3 continue / c

  • 作用:在 VM 处于暂停状态时,从当前断点/单步处继续执行,直到再次命中断点、单步、结束或错误。
  • 说明:若 VM 未暂停,会提示“VM未暂停,无法继续”。

4.4 step / s(单步进入)

  • 作用:执行一条指令;若该指令是“调用”,会进入被调用函数。
  • 说明:仅在 VM 为 READYPAUSED 时有效。

4.5 next / n(单步跳过)

  • 作用:执行到“当前栈帧”的下一条语句;若当前语句包含调用,不会进入被调用函数内部。
  • 说明:仅在 VM 为 READYPAUSED 时有效。

4.6 finish / f(跳出函数)

  • 作用:继续执行直到当前函数返回,停在调用方。
  • 说明:仅在 VM 为 READYPAUSED 时有效。

4.7 pause

  • 作用:在 VM 正在运行时请求暂停(例如正在 runcontinue 中)。
  • 说明:若 VM 未在运行,会提示“VM未运行,无法暂停”。

4.8 VM 状态与生命周期(了解即可)

  • READY:初始/重置后的状态,尚未开始执行;此时适合用 runstepnextfinish 开始调试。
  • RUNNING:正在连续执行脚本;可使用 pause 请求暂停,或等待命中断点/执行完成。
  • PAUSED:因命中断点、单步完成或手动 pause 而停下;此时可使用 continue 或再次单步(step/next/finish)。
  • STEP_MODE:内部用于处理单步逻辑的临时时态,用户通常只在开始和结束时看到“单步进入/跳过/跳出完成”等提示。
  • FINISHED:到达当前执行范围或字节码结尾;CLI 会打印“程序执行完成”,如需再次运行请先 reset,或直接 run(内部会隐式重新 start)。
  • ERROR:执行过程中发生错误(如栈下溢、未知指令等);CLI 会显示“错误: ...”,通常需要 reset 后重新尝试。

5. 断点管理

5.1 设置断点:break / b

  • 按行break <行号>
    示例:break 11b 20
    在源文件对应行设置断点;行号会解析为字节码位置(可能对应多条指令)。

  • 按函数break <函数名>
    示例:break mainb myFunc
    在该函数入口处设置断点。

  • 设置成功会输出断点 ID 及位置;断点会经 resolveBreakpoints 解析到具体 PC。

5.2 删除断点:delete / d

  • 用法delete <断点ID>
    示例:delete 1d 2
    按 ID 删除断点;若 ID 不存在会提示。

5.3 禁用/启用:disable / enable

  • 禁用disable <断点ID> — 断点保留但不触发。
  • 启用enable <断点ID> — 重新生效。

5.4 查看断点:info breakpoints / info bp

  • 列出所有断点,包括:ID、描述(行断点/函数断点)、状态(启用/禁用/待解析)、命中次数。

6. 查看信息

6.1 list / l [行号]

  • 无参数:以当前 PC 对应的源码行为中心,显示前后各 10 行;当前行用 => 标出。
  • 有参数list <行号> 以该行为中心显示上下文。
  • 若未加载到源码,会显示“(源码未加载)”。

6.2 stack

stack 用于查看当前 VM 的栈状态,包括主栈与副栈。

基本用法

  • stack
    显示 主栈副栈 的当前状态(从栈顶到底),每项以十六进制形式显示。
    行首 [...] 中的数字为从栈底开始的绝对索引,用于与执行语义对照。

  • stack main / stack alt / stack both
    仅显示主栈 / 仅显示副栈 / 同时显示两者。

按“高度(index,以栈底为 0)”查看

在下面的参数中,高度/索引统一采用“栈底为 0”的定义:

  • index = 0 表示栈底

  • index 越大越靠近栈顶;

  • CLI 输出中的 [...] 与这里的索引一致,都是从栈底开始的绝对索引

  • stack [main|alt|both] --near <H> [C]
    显示栈上某个高度附近的数据:

    • H:目标高度(从栈底开始,H = 0 为栈底);
    • C:上下文条数(可选,默认 5),实际显示范围为 [H − C, H + C],超出范围会自动裁剪。
  • stack [main|alt|both] --range <A:B>stack [main|alt|both] -r <A:B>
    显示高度范围 [A, B] 内的元素(含端点):

    • AB 都是从栈底开始的高度(0 为栈底);
    • A > B,内部会自动交换两者。

提示:

  • 若不带任何参数,则等价于 stack both,显示主栈与副栈的全部内容;
  • 上述参数只影响“显示哪些元素”,不改变栈本身的内容。

6.3 backtrace / bt

  • 显示调用栈:从当前帧到最外层,每层显示帧号、函数名、调用位置(源文件:行号)。

6.4 bytecode / bc [N]

  • 无参数:列出全部字节码,并标出当前 PC(=>),格式为:PC | 源码行号 | 指令
  • 有参数bytecode <N> 只显示当前 PC 前后各 N 条的上下文。
  • 源码行号来自调试信息,无对应行时显示 -

7. 停止时的自动显示

  • 当因断点命中单步暂停步进完成而停止时,若未关闭“停止时显示源码”选项,调试器会自动:
    • 输出当前停止原因;
    • 调用“当前位置”显示:源位置、PC、当前指令、以及当前行附近的源码(showCurrentLocation)。

8. 交易数据管理(合约调试)

适用于依赖“交易上下文”的合约(如使用 OP_PUSH_META 等)。

8.1 settxfile <文件名>

  • 作用:从文本文件加载交易相关数据到 VM,供执行时使用(主要用于配合 OP_PUSH_META 调试交易元数据)。
  • 文件格式:每行一个键值对 KEY:VALUE;行内 # 之后为注释;键不区分大小写。
  • 支持的键(与 OP_PUSH_META 条件值的对应关系)
说明
version交易版本
locktime锁定时间
inputCount输入数量
outputCount输出数量
inputsHash输入数据哈希
unlockingInput当前正在解锁的输入数据
outputsHash输出数据哈希
  • 数值均为 0x 十六进制;versionlocktimeinputCountoutputCount大小为4字节,小端序;加载成功后可用 showtx 查看。
  • settxfile 不会自动重置或重新执行脚本,一般在加载或更新交易数据后,需要配合 reset / run 或单步命令重新调试。

示例文件片段:

text
version: 02000000
locktime: 20a10700
inputCount: 02000000
outputCount: 01000000
inputsHash: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef
unlockingInput: 02ff01ab
outputsHash: 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

8.2 showtx

  • 显示当前已加载的交易数据:version、locktime、inputCount、outputCount、inputsHash、unlockingInput、outputsHash;二进制字段以十六进制打印。
  • 若未加载,会提示使用 settxfile <文件名> 加载。

9. 其他命令

  • help / h:在 REPL 内显示完整命令列表与简短说明。
  • quit / q / exit:退出调试器。
  • clear:清屏(输出多行空行)。

10. 命令历史与输入

  • 调试器会保留最近约 100 条命令历史(仅用于内部记录)。
  • 输入时首尾空格会被忽略;命令名会转为小写再匹配,因此大小写不敏感。

11. 错误与状态提示

  • 执行/单步:若 VM 未就绪或未暂停,会提示对应状态(如“VM未暂停,无法继续”、“VM未就绪,无法单步执行”)。
  • 断点:无效断点 ID 或无法解析的行号/函数名会给出明确错误或警告。
  • 交易文件:无法打开文件、键值格式错误或数值解析失败时,会输出错误并说明行号或键名。
  • 执行完成:到达执行范围或脚本末尾时,会输出“程序执行完成”;此时栈顶/栈内容即为最终执行结果,可通过 stack 查看。
  • 运行时错误:发生 VM 内部异常(如未知指令、栈操作非法等)时,会输出“错误: ...”,并进入错误状态;通常需要 reset 后重新执行。

12. 典型使用流程示例

  1. 启动并选函数/参数

    bash
    ./apc my.ct --debug

    按提示选择要调试的函数(或回车为所有公有函数填参数)。

  2. 设断点并运行

    text
    (apc-debug) break 10
    (apc-debug) break main
    (apc-debug) info breakpoints
    (apc-debug) run
  3. 停止后查看

    text
    (apc-debug) list
    (apc-debug) stack
    (apc-debug) backtrace
  4. 单步与继续

    text
    (apc-debug) next
    (apc-debug) step
    (apc-debug) continue
  5. 需要交易数据时

    text
    (apc-debug) settxfile test/tx_transaction_test.txt
    (apc-debug) showtx
    (apc-debug) run
  6. 重新运行

    text
    (apc-debug) reset
    (apc-debug) run
  7. 退出

    text
    (apc-debug) quit

13. 与构建/编译的关系

  • 调试器模式(--debug)会自动启用调试信息隐式编译指定源文件,无需单独传 -d--debug-output
  • 若需在非调试模式下仅生成调试信息(如导出到文件),请使用 -d--debug-output <file>,详见编译器帮助:apc -h

🇬🇧 English version

基于 MIT 许可发布