Я работаю на STM32F7.Hardfault срабатывает, когда я нажимаю free()
в следующем (упрощенном) коде:
typedef struct
{
uint8_t size;
uint8_t* data;
}my_struct;
void foo()
{
my_struct msg;
msg.size = 5;
msg.data = malloc(msg.size);
if(msg.data != NULL)
{
free(msg.data); // Hardfault
}
}
Шаг за шагом, используя GDB в free()
Я нашел инструкцию по сборке, которая вызвала Hardfault:
ldrd r1, r3, [r5, #8]
Значение r5
равно 0x5F0FE9D0
CFSR
равно 0x8200
, и оба регистра MMFAR
и BFAR
содержат 0x5F0FE9D8
,
Глядя на LDRDR проблемы в сети, я попытался добавить __attribute__((__packed__))
к my_struct
определению.Предполагается, что вместо принудительного доступа к памяти через указатели / структуры компилятор генерирует 2x LDR .
Благодаря этому у меня больше не возникает Hardfault во время выполнения.ОК ...
Из любопытства я хотел проверить адреса через GDB после этой модификации, и удивляюсь!Ничего не меняется (я имею в виду адреса), и я заканчиваю тем, что снова нажимаю на инструкцию LDRD , несмотря на packed
, и генерирую мой Hardfault (но только при выполнении отладки GDB).
Я запустил новый прогон после удаления атрибута и сравнил значение регистров MMFAR
и BFAR
, а когда я не в GDB, я получил 0x41AFFE60
- Почему я не вижу2x LDR в отладчике?
- В более общем смысле, почему у меня нет одинакового поведения с GDB и без него?
- Является ли уловка
packed
хорошим решением для моей проблемы?
PS Я использую FreeRTOS и определил configCHECK_FOR_STACK_OVERFLOW
для 2 и configASSERT
, ничего не срабатывает.