CoreDump_2021-05-26_14-40-18

dump log 显示是访问了非法内存地址

Memory Management fault: Data access violation @0x10000a0d

image-20210620130549455

trace 32 解析dump

死机时执行的汇编代码

str r0,[r3] ; pxBlockToInsert,[r3]

查看R3寄存器为 10000A0D

确实访问了内存地址 0x10000A0D

image-20210620130938468

再看调用栈情况

image-20210620150819656

死机位置

prvInsertBlockIntoFreeList

prvInsertBlockIntoFreeList 函数里面,在迭代寻找插入freeblock的位置,访问了0x10000A0D。

image-20210620163412567

!image-20210620162714790

而0x10000A0D并不是合法的一个8字节对齐的地址, 0x10000A0D & 0x07 = 5,所以会死机。

0x10000A0D 是怎么来的?

image-20210620153325267

pdata = 0x10092C90 的block大小是0x408, 减去header大小8也就是1024字节

image-20210620141934022

dump 0x10092C90 + 1024的内存数据,\r\n 正好是0x0D,0x0A,内存被踩。

1056 字节的数据是怎么来的?

image-20210620155459304

变量 apb_proxy_event_t apb_proxy_event; 未赋值初始化,可能会有问题。

image-20210620160200378

image-20210620161454398

1024 + 32 = 1056

所以死机根本原因是 0x10092C90 这段内存,写超了1024个字节导致。

CoreDump_2021-05-28_10-36-39

死机log

image-20210620201147511

对应代码,malloc 是,内存block划分得到的地址没有8字节对齐,触发了assert。

image-20210620201334192

也是内存被破坏的问题。

image-20210620165233727

image-20210620171829052

0x000A0D34 怎么来的?

A*34\r\n 正好是0A 0D 34,猜测也是内存overwrite问题。

image-20210620180931193

CoreDump_2021-05-28_10-51-25

死机log

image-20210620203453850

也是内存被踩问题。

image-20210620203423097

分析总结

  1. 检查访问的地址是否字节对齐,BC20平台的动态申请内存地址是按8字节对齐的,内存地址&0x07要等于0。
  2. 检查全局变量空闲内存列表xStart是否有非法内存地址,地址在不在heap地址范围,链表记录的block地址是否都是字节对齐的。
  3. 检查malloc返回的某个地址是否写穿,可以对该 (内存地址-0x8) 解析为 BlockLint_t * 结构体(head 大小占用8字节),查看这块内存分配的block大小,然后dump这段内存的结束地址,看下一个链表节点纪录的数据是否正常的,有没有被破坏。
  4. BC20平台使用的os是freertos, heap 内存分配策略是first fit方式,且从dump看,内存块的数据结构BlockLint_t 没有记录caller地址。