UNO R4 WiFi — Трассировка стека для отладки ошибок выполнения
Arduino UNO R4 WiFi использует CmBacktrace для вывода полезной информации от процессора Arm Cortex-M4 в виде последовательного вывода при возникновении ошибки времени выполнения. Вывод включает команду addr2line, которую можно использовать для получения трассировки стека (также обратная трассировка стека, или stack traceback), позволяющей найти источник ошибки.
В этом руководстве мы покажем, как включить эту функцию.
Необходимое оборудование и программное обеспечение
Просмотр ошибки времени выполнения
Чтобы получить информацию об ошибке времени выполнения в мониторе порта, выполните следующие шаги:
Убедитесь, что последовательное соединение инициализировано до возникновения ошибки, вызвав Serial.begin() в вашем скетче. Вы можете включить этот код в начало функции
setup():Serial.begin(115200); while (!Serial);
Подключите плату UNO R4 WiFi к компьютеру.
Откройте Монитор порта. Нажмите кнопку
Serial Monitor в правом верхнем углу или выберите Tools > Serial Monitor в строке меню.Если вы внесли какие-либо изменения в скетч, нажмите кнопку
Upload. В противном случае вы можете просто нажать кнопку RESET на плате.Если на плате произойдёт исключение, информация будет отображена в Мониторе порта.
Последовательный вывод.
После таблицы «Registers information» будет указан тип ошибки. Подробнее о типах можно прочитать здесь.
Последняя строка содержит команду для утилиты
addr2line. См. раздел `Запуск addr2line`_ для получения дополнительной информации.
Генерация трассировки стека
Вы можете использовать инструмент addr2line для генерации трассировки стека. Следуйте приведённым ниже инструкциям:
Примечание
addr2line недоступен как нативное приложение Windows, но его можно запустить с помощью Windows Subsystem for Linux (WSL).
Утилита addr2line включена в пакет плат Arduino UNO R4 Boards. Однако для запуска таким способом необходимо изменить команду, включённую в вывод. Для удобства вы можете установить addr2line в вашей системе.
Чтобы установить addr2line (опционально), используйте инструкции для вашей ОС:
Windows (WSL):
addr2lineнедоступен как нативное приложение Windows, но его можно запустить с помощью Windows Subsystem for Linux (WSL). Дистрибутив Ubuntu устанавливается по умолчанию и должен включатьaddr2line.macOS:
addr2lineможно установить с помощью Homebrew, выполнив командуbrew install binutilsв Терминале.Linux:
addr2lineможет быть уже установлен в вашей системе. В противном случае выполнитеapt-get install binutilsв Терминале (Ubuntu, Debian) или см. command-not-found.com/addr2line для других дистрибутивов.
1. Копирование команды addr2line
Windows (WSL):
Скопируйте команду из последовательного вывода.
Вставьте команду в текстовый редактор.
Замените
C:на/mnt/cи замените все обратные косые черты (\) на прямые косые черты (/).
macOS:
Скопируйте команду из последовательного вывода (изменения не требуются).
Linux:
Скопируйте команду из последовательного вывода (изменения не требуются).
Совет
Если вы не хотите устанавливать addr2line, вы можете использовать addr2line из пакета плат. Смотрите инструкции в разделе Копирование команды addr2line (пакет плат).
2. Запуск команды addr2line
Примечание
Скетч должен быть скомпилирован на том же компьютере, на котором вы запускаете addr2line.
Windows (WSL):
Откройте Windows Powershell.
Введите
Ubuntuв Windows Powershell и нажмитеEnter.Вставьте изменённую команду в Windows Powershell, щёлкнув правой кнопкой мыши по окну.
Нажмите
Enterдля выполнения команды.
macOS:
Откройте Терминал.
Нажмите
Cmd+Vдля вставки команды.Нажмите
Enterдля выполнения команды.
Linux:
Откройте Терминал.
Нажмите
Ctrl+Shift+Vдля вставки команды.Нажмите
Enterдля выполнения команды.
Также вы можете добавить флаг -p к вашей команде для более удобочитаемого формата.
3. Чтение вывода addr2line
По умолчанию команда выводит для каждого вызова функции следующее:
адрес:
0x00004188,0x0000426e, … (удалите флаг-a, если не хотите включать их)имя функции:
_ZN4UART5writeEh,loop, …номер строки:
/Users/sebastianwikstrom/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67, …
Выполните следующие шаги:
Найдите самую верхнюю строку в выводе, которая находится внутри вашего скетча. Число после пути — это номер строки, где произошла ошибка. Например,
/Users/username/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67указывает, что ошибка произошла в строке 67. Читая дальше по выводу, вы можете проследить обратно по вызовам функций, которые были сделаны.
Чтение трассировки стека addr2line в Терминале.
Откройте скетч в Arduino IDE и найдите номер строки из предыдущего шага (номер отображается слева от каждой строки).
Проанализируйте строку, где произошла ошибка, и попытайтесь понять, что могло вызвать ошибку.
Если вы не уверены, используйте функцию Serial.println() для вывода значений всех используемых переменных. Затем загрузите скетч снова и используйте последовательный вывод, чтобы увидеть состояния этих переменных перед возникновением ошибки.
Чтобы увидеть, откуда была вызвана функция, посмотрите на предыдущий вызов функции в выводе
addr2line.
В этом примере выход за границы массива numbers происходит после нескольких итераций цикла while(true):
Анализ кода.
Дополнительные инструкции
Копирование команды addr2line (пакет плат)
Примечание
Эти инструкции заменяют инструкции в разделе 1. Копирование команды addr2line.
Если вы хотите использовать addr2line непосредственно из пакета плат, следуйте приведённым ниже инструкциям.
Windows (WSL):
Скопируйте команду из последовательного вывода.
Вставьте команду в текстовый редактор.
Замените слово
addr2lineна/mnt/c/Users/User/Appdata/Local/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2lineДля пути к файлу после флага
-eзаменитеC:на/mnt/cи замените все обратные косые черты (\) на прямые косые черты (/).
macOS:
Скопируйте команду из последовательного вывода.
Вставьте команду в текстовый редактор.
Замените слово
addr2lineна~/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line.
Linux:
Скопируйте команду из последовательного вывода.
Вставьте команду в текстовый редактор.
Замените слово
addr2lineна.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line.