gpt4 book ai didi

c - 结构成员上的 free() 仅在调试中导致 Hardfault

转载 作者:行者123 更新时间:2023-12-01 12:06:14 25 4
gpt4 key购买 nike

我正在研究 STM32F7。当我在以下(简化的)代码中点击 free() 时会触发 Hardfault:

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
}
}

free() 中逐步使用 GDB 我找到了导致 Hardfault 的汇编指令:

ldrd    r1, r3, [r5, #8]

r5的值为0x5F0FE9D0

CFSR0x8200 并且 MMFARBFAR 寄存器都包含 0x5F0FE9D8

查看网上的LDRDR问题,我尝试将__attribute__((__packed__))添加到my_struct定义中。当通过指针/结构使用未对齐的内存访问时,它应该强制编译器生成 2xLDR

通过这样做,我在运行时不再有 Hardfault。好的...

出于好奇,我想在修改后通过 GDB 检查地址,惊喜!没有任何变化(我的意思是地址),我最终再次点击了 LDRD 指令,尽管 packed,并产生了我的 Hardfault(但仅在 GDB 调试执行中) .

删除属性后我启动了新的运行并比较了 MMFARBFAR 寄存器的值,当我不在 GDB 中时我得到了 0x41AFFE60

  • 为什么我在调试器中看不到 2xLDR
  • 更一般地说,为什么在使用和不使用 GDB 时我的行为不同?
  • packed 技巧是解决我的问题的好方法吗?

附言我正在运行 FreeRTOS 并将 configCHECK_FOR_STACK_OVERFLOW 定义为 2 和 configASSERT,没有触发。

最佳答案

0x5F0FE9D80x41AFFE60 在 STM32F7 内存映射(引用手册第 2 章)中都被标记为保留。这意味着堆已损坏

Why can't I see the 2xLDR in the debugger ?

因为free()在预编译的静态库中,所以不会重新编译。

More generally, why don't I have the same behavior with and without GDB ?

如果堆中包含随机垃圾,要么是因为它未正确初始化,要么是被一些不相关的代码覆盖,当您将东西连接到电路板或从电路板断开连接时,您可能会得到一些不同的垃圾。或者每当某些环境因素发生变化时。

Is the packed trick is the good solution for my issue ?

不,它只是靠运气设法隐藏了问题。对于损坏的堆,所有的赌注都会落空。

关于c - 结构成员上的 free() 仅在调试中导致 Hardfault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56582157/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com