Отладка
Программы Solana работают в сети, поэтому их отладка в дикой природе может быть сложной задачей. Чтобы упростить отладку программ, разработчики могут написать модульные тесты, которые напрямую проверяют выполнение их программы через среду выполнения Solana, или запустить локальный кластер, который позволит клиентам RPC взаимодействовать с их программой.
Запуск модульных тестов
Логирование
Во время выполнения программы как время выполнения, так и состояние журнала программы и сообщения об ошибках.
Для получения информации о том, как войти в программу, см. документацию по конкретному языку:
При запуске локального кластера журналы записываются в стандартный вывод, если они включены с помощью маски журнала «RUST_LOG». С точки зрения разработки программы полезно сосредоточиться только на журналах времени выполнения и программы, а не на остальных журналах кластера. Чтобы сосредоточиться на конкретной информации о программе, рекомендуется использовать следующую маску журнала:
экспортировать RUST_LOG=solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=info,solana_bpf_loader=debug,solana_rbpf=debug
Сообщения журнала, поступающие непосредственно из программы (а не из среды выполнения), будут отображаться в виде:
Журнал программы: <определенное пользователем сообщение>
Обработка ошибок
Объем информации, которая может быть передана через ошибку транзакции, ограничен, но существует множество точек возможных сбоев. Ниже приведены возможные точки сбоя и информация о том, каких ошибок следует ожидать и где получить дополнительную информацию:
- Загрузчик BPF может не разобрать программу, этого не должно происходить, так как загрузчик уже финализировал данные аккаунта программы.
InstructionError::InvalidAccountData
будет возвращен как часть ошибки транзакции.
- Загрузчик BPF может не настроить среду выполнения программы.
InstructionError::Custom(0x0b9f_0001)
будет возвращен как часть ошибки транзакции. «0x0b9f_0001» — это шестнадцатеричное представлениеVirtualMachineCreationFailed
.
- Загрузчик BPF мог обнаружить фатальную ошибку во время выполнения программы (например, паники, нарушения памяти, ошибки системных вызовов и т. д.).
InstructionError::Custom(0x0b9f_0002)
будет возвращен как часть ошибки транзакции. «0x0b9f_0002» — это шестнадцатеричное представлениеVirtualMachineFailedToRunProgram
.
- Программа сама может возвращать ошибку
InstructionError::Custom(<значение, определенное пользователем>)
будет возвращено. «Пользовательское значение» не должно конфликтовать ни с одной из встроенных ошибок программы выполнения . Программы обычно используют типы перечисления для определения кодов ошибок, начинающихся с нуля, чтобы они не конфликтовали.
В случае ошибок VirtualMachineFailedToRunProgram
дополнительная информация о специфике того, что не удалось, записывается в журналы выполнения программы.
Например, нарушение прав доступа, связанное со стеком, будет выглядеть примерно так:
Программа BPF 4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM не удалась: хранилище вне границ памяти (insn # 615), адрес 0x200001e38/8
Мониторинг расхода вычислительного бюджета
Программа может регистрировать оставшееся количество вычислительных единиц, которое ей будет разрешено, прежде чем выполнение программы будет остановлено. Программы могут использовать эти журналы для переноса операций, которые они хотят профилировать.
- Зарегистрировать оставшиеся вычислительные единицы из программы Rust
- Зарегистрировать оставшиеся вычислительные единицы из программы C
См. вычислить бюджет для получения дополнительной информации.
ELF Дамп
Внутреннее устройство общего объекта BPF можно сбросить в текстовый файл, чтобы получить более полное представление о составе программы и о том, что она может делать во время выполнения.
Трассировка инструкций
Во время выполнения интерпретатор BPF во время выполнения можно настроить для регистрации сообщения трассировки для каждой выполняемой инструкции BPF. Это может быть очень полезно для таких вещей, как точное определение контекста среды выполнения, ведущего к нарушению доступа к памяти.
Журналы трассировки вместе с дампом ELF могут дать много информации (хотя трассировки дают много информации).
Чтобы включить сообщения трассировки интерпретатора BPF в локальном кластере, настройте уровень solana_rbpf в RUST_LOG на значение трассировка. Например:
export RUST_LOG=solana_rbpf=trace