Как получить исключение по жесткой ошибке с помощью простой или инструкции на руке

В настоящее время мы охотимся за фантомом, который находится в форме, когда мы компилируем какой-либо код (без его вызова) один конкретный вызов memset генерирует исключение жесткой ошибки.

Адрес и длина, указанные для memset, действительны. Пошаговое выполнение в режиме одной инструкции показало, что он всегда терпит неудачу при выполнении инструкции ИЛИ. Но вместо вычисления значения процессор решает вызвать 0xffffffff9, а затем переходит к обработчику аппаратной ошибки с причиной неизвестной инструкции.

Разборка memset, где это происходит:

    0x80192f0  <+0x0020>        03 2c        cmp    r4, #3
    0x80192f2  <+0x0022>        2e d9        bls.n    0x8019352 <memset+130>
    0x80192f4  <+0x0024>        cd b2        uxtb    r5, r1
    # The following line crashes
    0x80192f6  <+0x0026>        45 ea 05 25  orr.w    r5, r5, r5, lsl #8
    0x80192fa  <+0x002a>        0f 2c        cmp    r4, #15
    0x80192fc  <+0x002c>        45 ea 05 45  orr.w    r5, r5, r5, lsl #16

Разборка 0xffffffff9:

    0xfffffff7                   00 00  movs    r0, r0
    0xfffffff9                   00 00  movs    r0, r0
    0xfffffffb                   00 00  movs    r0, r0

Где мы можем найти источник этого исключения?

Мы запускаем программное обеспечение на STM32F429II, который является Cortex-M4.


person Rudi    schedule 12.03.2019    source источник
comment
Какое ядро ​​ARM вы используете (или какой MCU)? Эта инструкция orr недоступна в ARMv6-M/Cortex-M0. Кроме того, в обработчике аппаратных сбоев вы можете просмотреть различные регистры состояния (например, HFSR, CFSR), чтобы узнать больше.   -  person starblue    schedule 12.03.2019
comment
Упс, вчера забыл добавить, что мы используем STM32F429II. Спасибо @starblue   -  person Rudi    schedule 13.03.2019


Ответы (2)


Имейте в виду, что для Cortex-M значение регистра ссылки указывает, как вернуться из исключения, а не адрес, на который нужно вернуться. Соответствующий адрес будет в стеке (при условии, что стек также не дал сбоев).

  • 0xFFFFFFFF1 Возврат в режим обработчика.
    Возврат из исключения получает состояние из основного стека. Выполнение использует MSP после возврата.

  • 0xFFFFFFF9 Возврат в режим потока.

    Исключение Вернуть состояние получения из основного стека. Выполнение использует MSP после возврата.

  • 0xFFFFFFFD Возврат в режим потока.

    Exception return получает состояние из стека процесса. Исполнение использует PSP после возврата.

Cortex-M также никогда не может выполнять код из «локального периферийного» пространства памяти.

person Sean Houlihane    schedule 12.03.2019

@Руди! Я надеюсь, что вы уже решили это. Я только что столкнулся с такой же проблемой и хотел бы поделиться своим опытом.

Тот факт, что MCU переходит в HardFault из-за инструкции orr.w, не означает, что ваша проблема в самой инструкции. Я использовал регистр HFSR (упомянутый @starblue), чтобы найти момент, когда он меняется. Если вы используете Eclipse — просто добавьте точку наблюдения памяти или

(uint32_t)*((uint32_t *) 0xE000ED2C)

к выражениям и найти строку, в которой значение становится не равным нулю.

В моем случае это была строка с присвоением значения нулевого указателя. И это было 15 сборочных линий до перехода к обработчику Hardfault. В вашем случае это может быть даже в другом потоке.

person Peter    schedule 19.06.2019