SIGTRAP несмотря на отсутствие установленных точек останова;скрытая аппаратная точка останова? - PullRequest
25 голосов
/ 23 марта 2012

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

SIGTRAP, Trap / точка останова trap

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

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

Ответы [ 5 ]

21 голосов
/ 23 марта 2012

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

4 голосов
/ 22 июня 2017

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

# Ones I hit the SIGTRAP:
(gdb) f 0  # Show the current stack frame of the current thread.
#0  0x4003ed70 in pthread_create@@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.
3 голосов
/ 29 марта 2012

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

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

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

1 голос
/ 19 октября 2017

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

На микроконтроллерах 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
1 голос
/ 28 марта 2012

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

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

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

...