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.