Перейти к содержанию

Точка наблюдения

Переменная внезапно портится, а кто её пишет — непонятно. Точка останова тут не поможет: она срабатывает на команде. Нужна точка наблюдения, которая срабатывает на обращении к адресу.

Обновлено Редакция GAW

Точка наблюдения (watchpoint) — аппаратное условие отладки, которое останавливает ядро при обращении к данным по заданному адресу: чтении, записи или любом доступе. Её родственница — точка останова — срабатывает на выборке команды. RM0090 описывает обе возможности отладки STM32F4 в одной фразе: ядро можно остановить на выборке команды или на обращении к данным, изучить состояние кристалла и продолжить выполнение (разд. 38.1).

Как устроена в Cortex-M

Точки наблюдения в Cortex-M даёт блок DWT (Data Watchpoint and Trace) рядом с ядром. Это набор компараторов, которые следят за адресами на шине данных. У STM32F4 их четыре, и каждый настраивается для одной из задач (RM0090, разд. 38.13):

  • аппаратная точка наблюдения — останов ядра;
  • запуск трассировки ETM;
  • выборка счётчика команд PC;
  • выборка адреса данных для трассировки.

У Cortex-M3 блок точек наблюдения может содержать одну или четыре точки в зависимости от конфигурации кристалла (Arm, Cortex-M3 TRM, разд. 7.1). В том же DWT живёт счётчик тактов CYCCNT. Отладчик программирует компараторы через порт доступа к отладке, то есть по JTAG или SWD, пока программа работает.

Другие архитектуры устроены похоже. Например, у ядра RISC-V в ESP32-C3 общий пул из восьми аппаратных точек, каждую можно сделать точкой останова или наблюдения (даташит ESP32-C3, разд. 4.1.1.1).

Когда она нужна

  • Порча переменной. Ставят точку наблюдения на запись по адресу переменной — ядро остановится вскоре после команды, которая пишет туда; событие асинхронное, поэтому виновник — среди последних выполненных команд (ARMv7-M ARM, разд. C1.8).
  • Выход за границу буфера. Наблюдают за словом сразу после массива: первая же запись туда — ошибка.
  • Переполнение стека. Точка наблюдения на нижней границе стека ловит момент, когда он залезает в чужую память.
  • Кто читает регистр. Наблюдение за чтением адреса периферии показывает, где программа опрашивает флаг.

Число точек невелико, поэтому для постоянной защиты памяти используют блок MPU, а точки наблюдения — как инструмент поиска конкретной ошибки. Как отладчик подключается к ядру и какие блоки отладки есть в Cortex-M — в статье «JTAG и SWD» и в обзоре ядра Cortex-M3.

Частые вопросы

Почему точкой останова не найти, кто портит переменную?

Точка останова срабатывает, когда ядро выбирает команду по заданному адресу. Точка наблюдения — когда программа читает или пишет данные по заданному адресу, какая бы команда это ни делала. Поэтому ею ловят, кто испортил переменную. Учтите: в ARMv7-M событие точки наблюдения асинхронно относительно вызвавшей его команды и обрабатывается как прерывание, так что ядро останавливается уже после обращения, иногда на несколько команд позже — виноватую команду ищут чуть выше места остановки.

Сколько точек наблюдения у STM32?

У STM32F4 блок DWT содержит четыре компаратора, и каждый можно настроить как точку наблюдения (RM0090, разд. 38.13). Но те же компараторы нужны и для других задач — запуска трассировки, выборок PC, — поэтому свободных под наблюдение может оказаться меньше. У Cortex-M3 в зависимости от конфигурации их одна или четыре.

Можно ли поставить точку наблюдения на массив?

Компараторов всего несколько. В Cortex-M регистр маски DWT_MASK позволяет одному компаратору игнорировать младшие биты адреса и следить за выровненной областью размером в степень двойки, но наибольшая маска зависит от реализации, поэтому большой массив произвольного размера целиком обычно не накрыть. Для массива наблюдают за его границей — за словом сразу после последнего элемента: так ловят выход за пределы буфера. Если нужна защита целой области, помогает блок защиты памяти MPU: запись в запрещённую область вызывает исключение.

Источники

  1. STMicroelectronics. RM0090 Reference manual STM32F405/415, STM32F407/417, STM32F427/437, STM32F429/439 (Rev 21) — разд. 38.1: ядро можно остановить на выборке команды (breakpoint) или на обращении к данным (watchpoint), затем изучить состояние и продолжить выполнение; разд. 38.13: DWT состоит из четырёх компараторов, каждый настраивается как аппаратная точка наблюдения, запуск ETM, выборка PC или выборка адреса данных; счётчики тактов, сна, операций загрузки и сохранения и др.
  2. Arm. Cortex-M3 Processor Technical Reference Manual, r2p1 (ARM 100165_0201_02_en) — разд. 7.1: блок точек наблюдения — одна или четыре в зависимости от конфигурации; разд. 8: DWT — до четырёх компараторов, настраиваемых как аппаратная точка наблюдения
  3. Espressif Systems. ESP32-C3 Series Datasheet (version 2.4) — разд. 4.1.1.1: ядро RISC-V — до 8 аппаратных точек останова или наблюдения, JTAG для отладки
  4. Arm. ARMv7-M Architecture Reference Manual (ARM DDI 0403C) — разд. B1.5: исключение DebugMonitor обычно синхронное, но точки наблюдения асинхронны и ведут себя как прерывание; разд. C1.8: событие точки наблюдения асинхронно относительно вызвавшей его команды; табл. C1-33: DWT_MASKx — размер маски игнорируемых младших бит адреса (0–31), наибольший размер зависит от реализации

Нашли ошибку?