Skip to main content

调试

Solana程序在链上运行,因此在链外调试可能会很困难。 为了使调试程序更容易,开发人员可以编写单元测试以通过Solana运行时直接测试其程序的执行情况,或者运行允许RPC客户端与其程序进行交互的本地集群。

运行单元测试#

记录#

在程序执行期间,运行时,程序日志状态和错误消息均会出现。

有关如何从程序登录的信息,请参阅特定语言的文档:

运行本地集群时,只要通过RUST_LOG日志掩码启用了日志,日志就会写入stdout。 从程序开发的角度来看,仅关注运行时和程序日志,而不关注其余的集群日志会有所帮助。 为了专注于程序特定的信息,建议使用以下日志掩码:

export RUST_LOG=solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=info,solana_bpf_loader=debug,solana_rbpf=debug

直接来自程序(而不是runtime) 的日志消息将以以下形式显示:

Program log: <user defined message>

错误处理#

可以通过事务错误传达的信息量是有限的,但是有很多可能的失败点。 以下是可能的故障点,有关预期发生哪些错误以及在何处获取更多信息的信息:

  • BPF加载程序可能无法解析程序,这应该不会发生,因为加载程序已经对程序的帐户数据进行了最终处理
    • InstructionError::InvalidAccountData将作为交易错误的一部分返回。
  • BPF加载程序可能无法设置程序的执行环境
    • InstructionError::Custom(0x0b9f_0001)将作为交易错误的一部分返回。 "0x0b9f_0001"是VirtualMachineCreationFailed的十六进制表示形式。
  • BPF加载程序可能在程序执行过程中检测到致命错误(紧急情况,内存冲突,系统调用错误等)。
  • 程序本身可能返回错误
    • InstructionError::Custom(<user defined value>)将被返回。 “用户定义的值”不得与任何内置运行时程序错误相冲突 。 程序通常使用枚举类型来定义从零开始的错误代码,因此它们不会冲突。

如果出现VirtualMachineFailedToRunProgram错误,则将有关失败原因的详细信息写入程序的执行日志

例如,涉及堆栈的访问冲突将如下所示:

BPF程序4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM失败:out of bounds memory store (insn #615), addr 0x200001e38/8

监控计算预算消耗#

程序可以记录停止程序执行之前将允许的剩余计算单元数。 程序可以使用这些日志来包装希望分析的操作。

有关更多信息,请参见计算预算

ELF转储#

可以将BPF共享对象的内部信息转储到文本文件中,以更深入地了解程序的组成及其在运行时的工作方式。

指令追踪#

在执行期间,可以将运行时BPF解释器配置为记录每个执行的BPF指令的跟踪消息。 对于诸如精确指出导致内存访问冲突的运行时上下文之类的事情,这可能非常有用。

跟踪日志与ELF转储一起可以提供更多参考(尽管跟踪会产生很多信息)。

要在本地集群中打开BPF解释器跟踪消息,请将RUST_LOG中的solana_rbpf级别配置为trace。 例如:

export RUST_LOG=solana_rbpf=trace