UNO R4 WiFi — Трассировка стека для отладки ошибок выполнения

Arduino UNO R4 WiFi использует CmBacktrace для вывода полезной информации от процессора Arm Cortex-M4 в виде последовательного вывода при возникновении ошибки времени выполнения. Вывод включает команду addr2line, которую можно использовать для получения трассировки стека (также обратная трассировка стека, или stack traceback), позволяющей найти источник ошибки.

В этом руководстве мы покажем, как включить эту функцию.

Необходимое оборудование и программное обеспечение

Просмотр ошибки времени выполнения

Чтобы получить информацию об ошибке времени выполнения в мониторе порта, выполните следующие шаги:

  1. Убедитесь, что последовательное соединение инициализировано до возникновения ошибки, вызвав Serial.begin() в вашем скетче. Вы можете включить этот код в начало функции setup():

    Serial.begin(115200);
    while (!Serial);
    
  2. Подключите плату UNO R4 WiFi к компьютеру.

  3. Откройте Монитор порта. Нажмите кнопку symbol_monitor Serial Monitor в правом верхнем углу или выберите Tools > Serial Monitor в строке меню.

  4. Если вы внесли какие-либо изменения в скетч, нажмите кнопку symbol_upload Upload. В противном случае вы можете просто нажать кнопку RESET на плате.

  5. Если на плате произойдёт исключение, информация будет отображена в Мониторе порта.

Последовательный вывод

Последовательный вывод.

  1. После таблицы «Registers information» будет указан тип ошибки. Подробнее о типах можно прочитать здесь.

  2. Последняя строка содержит команду для утилиты 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):

  1. Скопируйте команду из последовательного вывода.

  2. Вставьте команду в текстовый редактор.

  3. Замените C: на /mnt/c и замените все обратные косые черты (\) на прямые косые черты (/).

macOS:

Скопируйте команду из последовательного вывода (изменения не требуются).

Linux:

Скопируйте команду из последовательного вывода (изменения не требуются).

Совет

Если вы не хотите устанавливать addr2line, вы можете использовать addr2line из пакета плат. Смотрите инструкции в разделе Копирование команды addr2line (пакет плат).

2. Запуск команды addr2line

Примечание

Скетч должен быть скомпилирован на том же компьютере, на котором вы запускаете addr2line.

Windows (WSL):

  1. Откройте Windows Powershell.

  2. Введите Ubuntu в Windows Powershell и нажмите Enter.

  3. Вставьте изменённую команду в Windows Powershell, щёлкнув правой кнопкой мыши по окну.

  4. Нажмите Enter для выполнения команды.

macOS:

  1. Откройте Терминал.

  2. Нажмите Cmd + V для вставки команды.

  3. Нажмите Enter для выполнения команды.

Linux:

  1. Откройте Терминал.

  2. Нажмите Ctrl + Shift + V для вставки команды.

  3. Нажмите Enter для выполнения команды.

Также вы можете добавить флаг -p к вашей команде для более удобочитаемого формата.

3. Чтение вывода addr2line

По умолчанию команда выводит для каждого вызова функции следующее:

  • адрес: 0x00004188, 0x0000426e, … (удалите флаг -a, если не хотите включать их)

  • имя функции: _ZN4UART5writeEh, loop, …

  • номер строки: /Users/sebastianwikstrom/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67, …

Выполните следующие шаги:

  1. Найдите самую верхнюю строку в выводе, которая находится внутри вашего скетча. Число после пути — это номер строки, где произошла ошибка. Например, /Users/username/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67 указывает, что ошибка произошла в строке 67. Читая дальше по выводу, вы можете проследить обратно по вызовам функций, которые были сделаны.

Чтение трассировки стека addr2line в Терминале

Чтение трассировки стека addr2line в Терминале.

  1. Откройте скетч в Arduino IDE и найдите номер строки из предыдущего шага (номер отображается слева от каждой строки).

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

  • Если вы не уверены, используйте функцию Serial.println() для вывода значений всех используемых переменных. Затем загрузите скетч снова и используйте последовательный вывод, чтобы увидеть состояния этих переменных перед возникновением ошибки.

  • Чтобы увидеть, откуда была вызвана функция, посмотрите на предыдущий вызов функции в выводе addr2line.

В этом примере выход за границы массива numbers происходит после нескольких итераций цикла while(true):

Анализ кода

Анализ кода.

Дополнительные инструкции

Копирование команды addr2line (пакет плат)

Примечание

Эти инструкции заменяют инструкции в разделе 1. Копирование команды addr2line.

Если вы хотите использовать addr2line непосредственно из пакета плат, следуйте приведённым ниже инструкциям.

Windows (WSL):

  1. Скопируйте команду из последовательного вывода.

  2. Вставьте команду в текстовый редактор.

  3. Замените слово addr2line на /mnt/c/Users/User/Appdata/Local/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line

  4. Для пути к файлу после флага -e замените C: на /mnt/c и замените все обратные косые черты (\) на прямые косые черты (/).

macOS:

  1. Скопируйте команду из последовательного вывода.

  2. Вставьте команду в текстовый редактор.

  3. Замените слово addr2line на ~/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line.

Linux:

  1. Скопируйте команду из последовательного вывода.

  2. Вставьте команду в текстовый редактор.

  3. Замените слово addr2line на .arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line.