vxworks issue: load DKM fail

1. 问题现象

在调试Am5728 + vxworks时,,同时加载算法模块DKM(.out)和通讯模块DKM(.out)文件时,发现有内存分配失败的打印,业务无法启动。
在这里插入图片描述

另外应用还有反馈,如果算法模块中定义了太多的静态变量,会造成通讯模块无法加载。

2. 定位过程

step 1. 排查出错地址在哪个区域?

仔细看了一下出错的地址0x50d440,这个地址是落在Kernel System Virtual Memory区域当中的。

整个Vxworks的地址空间划分如下:
在这里插入图片描述
我们使用adrSpaceShow()函数验证一下当前的单板地址空间配置是否符合:

-> adrSpaceShow

Global RAM Pool Info:
---------------------
  Allocation unit size:                        0x1000     4.0kB
  Total size:                              0x7c000000     1.9GB
  Allocated:                                0x751f000   117.1MB
  Free:                                    0x74ae1000     1.8GB
  Largest contiguous free block:           0x74ae1000     1.8GB


Shared User Virtual Memory Region Info:
---------------------------------------
  Allocation unit size:                        0x1000     4.0kB
  Total size:                              0x20000000   512.0MB
  Allocated:                                        0     0.0
  Free:                                    0x20000000   512.0MB
  Largest contiguous free block:           0x20000000   512.0MB


RTP Private Virtual Memory Region Info:
---------------------------------------
  RTP component included:                         Yes
  RTP Address Space:                       Overlapped
  RTP code region base:                    0x80000000
  RTP code region size:                    0x60000000     1.5GB


Kernel System Virtual Memory Info:
----------------------------------
  System Region Base:                      0000000000
  System Region Size:                      0x20000000   512.0MB


Kernel Virtual Memory Pool Region Info:
---------------------------------------
  Allocation unit size:                        0x1000     4.0kB
  Total size:                              0x60000000     1.5GB
  Allocated:                                0x62ba000    98.7MB
  Free:                                    0x59d46000     1.4GB
  Largest contiguous free block:           0x59d46000     1.4GB
value = 0 = 0x0

总结:当前单板符合vxworks的地址空间模型,出错地址0x50d440范围确认在Kernel System Virtual Memory

step 2. 大胆尝试

出错信息block too big 1441480 bytes (0x8 aligned) in partition 0x50d440,是提示分配空间太大。要么是内存池(Heap/Memory Partition)的空间不足,或者是要分配的空间太大超过了系统允许的最大限制。

partition 0x50d440看起来这个地址是一个内存池地址,我们尝试来看看是不是?

我们找到了Memory Partition的一些调试函数:

memShow( ) - show blocks and statistics for the current heap partition
memPartShow( ) - show available and allocated memory in specified partition

STATUS memShow
    (
    int type   /* 0 = summary, 1 = list all blocks in the free list, */
               /* 2 = list all sections */
    )       

STATUS memPartShow
    (
    PART_ID partId,   /* memory partition ID                   */
    int     type      /* 0 = statistics, 1 = statistics & list */
                      /* 2 = statistics & list & extra info    */
    )     

尝试使用,地址的确是一个内存池的地址:

-> memPartShow(0x50d440,2)

LIST OF FREE BLOCKS:
         number      size        addr
        --------  ----------  ----------
        Free block list truncated for printing (823 more)


LIST OF MEMORY SECTIONS ADDED TO THE PARTITION:
        start addr     size
        ----------  ----------
        0x00524300    16748536
        0x0051f300       20480

OPTIONS:
        ALLOC_ERROR_EDR_WARN
        ALLOC_ERROR_LOG
        BLOCK_ERROR_EDR_WARN
        BLOCK_ERROR_LOG
        BLOCK_ERROR_SUSPEND

SUMMARY:
  status       bytes       blocks    avg block  max block
 -------- -------------- ---------- ---------- ----------
current
 free            4425792        823       5377    1159880
 alloc          12342712        877      14073          -
 internal            408          2        204          -
cumulative
 alloc          12347032        879      14046          -
peak
 alloc          12343120          -          -          -
value = 0 = 0x0

这里的内存池大概16M,已经用了12M,剩余4M,最大连续空间为1.1M。的确存在内存分配不到的风险。

联想到Kernel System Virtual Memory区域只有一个内存池Kernel Proximity Heap,作用就是用来加载模块的。

我们在VIP工程中查看Kernel Proximity Heap的大小:

#define KERNEL_PROXIMITY_HEAP_SIZE 0x1000000

刚好为16M,基本上肯定就是Kernel Proximity Heap了。

总结:0x50d440确认是Kernel Proximity Heap内存池地址,而且这个内存池的确存在分配不到1.4M内存的情况和现象吻合。

3. 结论

修改一个Kernel Proximity Heap大小为32M的版本,给应用测试,测试ok,问题解决。

#define KERNEL_PROXIMITY_HEAP_SIZE 0x2000000
posted @ 2020-11-01 10:22  pwl999  阅读(221)  评论(0编辑  收藏  举报