Подтвердить что ты не робот

SIGTRAP, несмотря на отсутствие установленных контрольных точек; скрытая аппаратная точка останова?

Я отлаживаю эту часть программного обеспечения для встроенной системы STM32. В одной из функций мои программы продолжают сталкиваться с некоторой точкой останова:

SIGTRAP, ловушка Trace/breakpoint

Однако в GDB, когда я делаю info breakpoints, я получаю No breakpoints or watchpoints. Точка останова фактически соответствует точке останова, которую я установил довольно давно, в другой версии исполняемого файла. Когда я установил эту точку останова, GDB сказал мне automatically using a hardware breakpoint on read-only memory (или подобное сообщение).

Я думаю, что аппаратная точка останова остается на моем чипе, несмотря на загрузку новой версии программного обеспечения. Если есть действительно ложная точка останова, как я могу ее найти и удалить?

4b9b3361

Ответ 1

Ok. Длительный ответ: Аппаратные точки останова обычно устанавливаются путем записи в некоторые специальные регистры процессора. Это делается gdb. Если gdb умирает, он может оставить те, которые установлены в CPU. Я предполагаю, что ваша реализация (из gdb) не очищает и не проверяет их при подключении к вашей цели. Чтобы найти их, вам нужно будет указать содержимое регистров аппаратных прерываний на вашем CPU (не знаете, как это сделать на STM32). Обходным путем было бы (информированное предположение) следующее: установить несколько контрольных точек HW (обычно их всего несколько, редко больше 8) с помощью gdb, а затем удалить все из них. Это должно перезаписать, а затем очистить эти регистры. После того, как вы установите эти точки останова (перед их удалением), выполните "продолжить" (на всякий случай, когда gdb устанавливает точки останова только в это время).

Ответ 2

SIGTRAP должен быть командой останова, которая выполняется.

Отлаживайте это, проверяя указатель на инструкцию, он скорее всего указал на адрес, содержащий инструкцию BKPT (вам нужно будет посмотреть, что представляет собой фактический код).

Оттуда вам придется работать в обратном направлении на основе указателя стека и инструкции и посмотреть, где вы ожидаете. Могло быть несколько причин, из-за которых GDB вставляет инструкцию точки останова, которую он не смог очистить, к повреждению памяти.

Ответ 3

Мне помогли следующее:

# Ones I hit the SIGTRAP:
(gdb) f 0  # Show the current stack frame of the current thread.
#0  0x4003ed70 in [email protected]@GLIBC_2.4 () from /opt/CodeSourcery/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libpthread.so.0

# The fragment of interest is the current address: 0x4003ed70.
# Set the hardware assisted breakpoint at the current address:
(gdb) hbreak *0x4003ed70

# Continue execution (without hitting SIGTRAP):
(gdb) c
# Continuing.

Ответ 4

Код, который вы используете, может содержать

int $0x03 ; talking about x86, don't know STM32 mnemo

который вызывает SIGTRAP.

Ответ 5

Если добавление и удаление аппаратных контрольных точек не помогает, проверьте вектор прерывания.

На микроконтроллерах Cortex-M все записи обработчиков должны иметь нечетный адрес (ARM Cortex-M FAQ). Если они этого не делают, то запускается UsageFault типа INVSTATE и MCU останавливается. GDB интерпретирует это как SIGABRT.

Если одна из записей имеет четный адрес, проверьте, есть ли у функции обработчика директивы .thumb_func и .type(NXP Избегайте жесткого отказа, HardFault и .thumb_func).

Пример для HardFault_Handler:

.thumb_func
.type HardFault_Handler, %function
HardFault_Handler:
  TST LR, #4
  ITE EQ
  MRSEQ R0, MSP
  MRSNE R0, PSP
  B hard_fault_handler_c