关于U-boot中malloc返回失败

最近在使用ELDK(arm-linux-) u-boot 1.3.0 时候遇到到网上盛传的 malloc 返回指针为0的怪问题

(DL)malloc 调用流程为:

->malloc() //dlmalloc.c

->mALLOc() //dlmalloc.c

->malloc_extend_top() //dlmalloc.c

->sbrk() //board.c ----->mem_malloc_init() -------> CFG_MALLOC_LEN

即首次使用malloc时堆中的可用缓冲区字节数为0. 然后根据DLMALLOC 的算法会通过sbrk函数去往堆中添加内存(最多CFG_MALLOC_LEN bytes)。调试记录如下:

nf: malloc() nb=65544,bytes=65536
nf:remainder_size = -65544 bytes
nf:chunksize(top) = 0 bytes
nf:nb = 65544 bytes
nf: this is func malloc_extend_top()
nb = 65544
top_pad = 6291456 !!!!!!!!!!error
MINSIZE = 16
sbrk_size = 6357016
sbrk_size = 6357016
nf: calling sbrk(sbrk_size = 6357016 bytes)
nf:this is func sbrk() start, increment = 6357016 bytes
nf: sbrk return fail, 55555~~~~~
nf:this is func sbrk() start, increment = 4072 bytes
nf: malloc fail:(

从调试记录中可见top_pad 值异常,top_pad的声明以及解释如下:

static unsigned long top_pad          = DEFAULT_TOP_PAD; // =0
/*
    M_TOP_PAD is the amount of extra `padding' space to allocate or
      retain whenever sbrk is called. It is used in two ways internally:

      * When sbrk is called to extend the top of the arena to satisfy
 a new malloc request, this much padding is added to the sbrk
 request.

      * When malloc_trim is called automatically from free(),
 it is used as the `pad' argument.

      In both cases, the actual amount of padding is rounded
      so that the end of the arena is always a system page boundary.

      The main reason for using padding is to avoid calling sbrk so
      often. Having even a small pad greatly reduces the likelihood
      that nearly every malloc request during program start-up (or
      after trimming) will invoke sbrk, which needlessly wastes
      time.

      Automatic rounding-up to page-size units is normally sufficient
      to avoid measurable overhead, so the default is 0.  However, in
      systems where sbrk is relatively slow, it can pay to increase
      this value, at the expense of carrying around more memory than
      the program needs.

*/

可见top_pad赋初值为0, 在malloc_extend_top() 中调用到的值却为6291456从而导致内存分配失败。尝试着仅仅将此值改为1024,1,2 等非零值则一切正常,真是奇怪!!!

debug 记录如下(top_pad = 1024):

nf: malloc() nb=65544,bytes=65536
nf:remainder_size = -65544 bytes
nf:chunksize(top) = 0 bytes
nf:nb = 65544 bytes
nf: this is func malloc_extend_top()
nb = 65544
top_pad = 1024 !!!correct
MINSIZE = 16
sbrk_size = 66584
sbrk_size = 66584
nf: calling sbrk(sbrk_size = 66584 bytes)
nf:this is func sbrk() start, increment = 66584 bytes
nf:this is func sbrk() start, increment = 3048 bytes

结论: 在使用denx 自带的 arm-linux-gcc 编译 u-boot 时候将dlmalloc.c 中 top_pad 赋值改成1024(或其他非0值)即可

避免malloc分配内存失败的问题。如下:

static unsigned long top_pad          = 1024;//DEFAULT_TOP_PAD; // =0

但是此问题发生的root cause还需高手指点,本文只期望能够抛砖引玉^^



应是bss段未清0造成的,在start.S中显式的清0  Bss段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值