Отладчик: пауза, шаг, перемотка
Пауза, шаг по одной команде, точки останова и — на платах Arduino — перемотка назад.
Вкладка «Отладка» видна администратору сайта.
Пауза и шаг
Пауза — не «стоп». «Стоп» гасит модель, и состояние исчезает вместе с ней; пауза оставляет модель живой и позволяет пойти дальше.
Шаг — одна команда, а не один такт: команды бывают многотактными, и шаг на такт останавливался бы посреди команды.
На паузе у платы Arduino видны все тридцать два регистра и флаги буквами: SREG = 0x22 не говорит ничего, а ZI говорит, что результат нулевой и прерывания разрешены. У ESP32 регистров сто с лишним, и показывать их окном бессмысленно — вместо них след последних команд.
Точки останова
Ставятся по именам функций, а не по строкам исходника.
Строки потребовали бы разбора отладочной информации, которого у нас нет. Имена лежат в таблице символов, которую мы и так читаем — ради имён в отчёте об аварии.
С точками останова модель идёт по одной команде за раз. Иначе проверять счётчик команд можно было бы только на краях порции, а порция — это тысячи команд, и остановка приходила бы не туда. Медленнее в разы, и это правильная цена: платит её только тот, кто отлаживает.
Перемотка
Ползунок времени двигает модель назад — есть только на платах Arduino.
Причина в размере состояния. У ATmega328P оно два с половиной килобайта, и сотня снимков занимает четверть мегабайта. У ESP32 состояние — полмегабайта, и сотня снимков съела бы полсотни мегабайт памяти вкладки. У таких моделей ползунок прячется, а не показывается неработающим.
Держится перемотка на одном свойстве: той же прошивкой из того же состояния модель проходит тот же путь. Если это не так, ползунок показывает не прошлое, а другое будущее — худший из исходов, потому что выглядит правдоподобно. Это свойство проверяется отдельным тестом.
Восстанавливается ближайший снимок не позже запрошенного времени, а дальше модель доигрывается вперёд. Прыжок прямо на снимок ставил бы ползунок только в те точки, где снимок случайно оказался.
Чего у ядра на C нет
У ESPLab два ядра эмуляции ESP32: одно на JavaScript, второе собрано в WebAssembly и быстрее.
У второго точки останова и пошаговое исполнение не работают: оно крутит порцию команд целиком внутри WebAssembly. Притворяться, что работают, нельзя — вы поставите точку, модель её проедет, и вы решите, что до этого места код не доходит.
Следа команд у него тоже нет, и вместо выдуманного отдаётся пустой: пустой список читается как «нет данных», выдуманный — как данные.