Отладчик: пауза, шаг, перемотка

Пауза, шаг по одной команде, точки останова и — на платах Arduino — перемотка назад.

Вкладка «Отладка» видна администратору сайта.

Пауза и шаг

Пауза — не «стоп». «Стоп» гасит модель, и состояние исчезает вместе с ней; пауза оставляет модель живой и позволяет пойти дальше.

Шаг — одна команда, а не один такт: команды бывают многотактными, и шаг на такт останавливался бы посреди команды.

На паузе у платы Arduino видны все тридцать два регистра и флаги буквами: SREG = 0x22 не говорит ничего, а ZI говорит, что результат нулевой и прерывания разрешены. У ESP32 регистров сто с лишним, и показывать их окном бессмысленно — вместо них след последних команд.

Точки останова

Ставятся по именам функций, а не по строкам исходника.

Строки потребовали бы разбора отладочной информации, которого у нас нет. Имена лежат в таблице символов, которую мы и так читаем — ради имён в отчёте об аварии.

С точками останова модель идёт по одной команде за раз. Иначе проверять счётчик команд можно было бы только на краях порции, а порция — это тысячи команд, и остановка приходила бы не туда. Медленнее в разы, и это правильная цена: платит её только тот, кто отлаживает.

Перемотка

Ползунок времени двигает модель назад — есть только на платах Arduino.

Причина в размере состояния. У ATmega328P оно два с половиной килобайта, и сотня снимков занимает четверть мегабайта. У ESP32 состояние — полмегабайта, и сотня снимков съела бы полсотни мегабайт памяти вкладки. У таких моделей ползунок прячется, а не показывается неработающим.

Держится перемотка на одном свойстве: той же прошивкой из того же состояния модель проходит тот же путь. Если это не так, ползунок показывает не прошлое, а другое будущее — худший из исходов, потому что выглядит правдоподобно. Это свойство проверяется отдельным тестом.

Восстанавливается ближайший снимок не позже запрошенного времени, а дальше модель доигрывается вперёд. Прыжок прямо на снимок ставил бы ползунок только в те точки, где снимок случайно оказался.

Чего у ядра на C нет

У ESPLab два ядра эмуляции ESP32: одно на JavaScript, второе собрано в WebAssembly и быстрее.

У второго точки останова и пошаговое исполнение не работают: оно крутит порцию команд целиком внутри WebAssembly. Притворяться, что работают, нельзя — вы поставите точку, модель её проедет, и вы решите, что до этого места код не доходит.

Следа команд у него тоже нет, и вместо выдуманного отдаётся пустой: пустой список читается как «нет данных», выдуманный — как данные.