1.关键词

camera 稳定性测试,ion泄漏;

2.问题描述

环境 设备型号:某OpenHarmony 芯片适配项目 系统版本:基于OpenHarmony 3.2.1Release的定制适配版 问题现象:在某芯片适配稳定性测试时,发现系统应用遍历连续测试48个小时以上后,系统出现大量appfreeze问题。日志中也出现了ION内存分配失败的打印。

img

 

3.问题原因

3.1 正常机制

camera_host底层库相机设备打开时申请了3个ION内存,在mmap函数也申请了3个ION内存,6个ION内存在munmap函数执行时进行了检查,并都被集中释放了。

3.2 异常机制

camera快速打开以及关闭测试过程中,一旦camera_host适配层启动的线程,还没有执行到底层库的mmap函数时,就收到了相机设备关闭命令,线程快速退出了。此时camera设备关闭过程中,底层mmap函数和munmap函数都没有机会执行,对应的相机设备打开时申请的3个ION内存就没有释放,会造成ION内存泄漏。

4.解决方案

在底层库的关闭函数中对底层库申请的ION内存进行检查,如果发现ION内存没有释放,进行ion的释放操作。

int ***V4l2AdapterImpl::close(int fd) {
  ......
  /*---start---新增代码如下:对ION内存进行检测并释放---start---*/
  int tmp = mPreviewHeapNum;
  for (int i = 0; i < tmp; i++) {
    if (mFullPathDataHeap[i]) {
      if (mFullPathDataHeap[i]->ion_heap) {
        delete mFullPathDataHeap[i]->ion_heap;
        mFullPathDataHeap[i]->ion_heap = NULL;
      }
      free(mFullPathDataHeap[i]);
      mFullPathDataHeap[i] = NULL;
      mPreviewHeapNum--;
    }
  }
  /*---end---新增代码如上:对ION内存进行检测并释放---end---*/
  ......
  return ret;
}

 

5.定位过程

5.1、对系统进行系统应用遍历测试(含camera应用按钮打开、关闭、拍照、图库处理随机点击测试),并执行smaps-show内存监测脚本,监测系统当前运行的各进程内存情况,确认较长时间测试时,camera_host使用的内存呈斜线增长,存在内存泄漏情况。

img

 

 

5.2、对比压测出问题时的camera_host模块与开机启动后的camera_host模块使用的栈内存,堆内存值,确认其内存值基本变化不大。先排除了camera_host模块堆和栈内存引发内存泄漏的情况。

image-20230706154721476

 

5.3、因为当前适配的芯片camera库用到了ION内存处理图像数据,我们通过如下命令和测试方法,查看与分析ION内存的使用数量,确认camera模块存在ION内存泄漏:

cat /sys/kernel/debug/dma_buf/bufinfo | grep ion | wc -l

5.3.1、我们统计到的正常情况的camera子系统ION使用情况如下:

开机启动后,相机首次开启前,统计到系统使用到的ION数量为0:

image-20230705194118068

 

相机首次开启后(未发生ION内存泄漏),统计到系统使用到的ION内存(含camera预览显示用的DRM ION内存等)数量为14:

image-20230705194454777

 

相机退出后,统计到系统使用到的ION内存数量为0:说明当前camera子系统没有发生ION内存泄漏:

image-20230705194118068

 

5.3.2、单纯相机应用长时间压测后,退出相机app,统计到系统使用到的ION内存数量为60,ION内存泄漏数量累积达到60个:

image-20230705194118068

 

5.4、对camera_host模块中分配和释放ion内存的地方,都添加分配和释放次数日志打印,指定各条日志打印的都携带关键字“MemIon”,方便搜索以及日志过滤。

5.4.1、开启OpenHarmony日志落盘:

hdc_std.exe shell rm /data/log/hilog/* -rf
hdc_std.exe shell rm /data/log/faultlog/faultlogger/* -rf
hdc_std.exe shell hilog -p off
hdc_std.exe shell hilog -w start

5.4.2、在hdc shell窗口,开启hilog实时过滤“MemIon”关键字的显示,使用的过滤命令如下:

hdc_std.exe shell
#hilog | grep "MemIon"

5.4.3、开启“MemIon”关键字的过滤显示后,手动快速乱序点击相机app和退出按钮。

正常释放的日志打印应该是释放次数与分配次数对应:如下:

image-20230706155235029

 

当抓取到相机退出后MemIon释放次数未归0的情况时,说明抓取到了漏释放情况,如下图:

image-20230706154300593

 

记住漏释放时间12:17:26,退出相机,停止测试。

5.4.4、停止落盘,压缩并拉取日志:

hdc_std.exe shell hilog -w stop
hdc_std.exe shell tar cvf /data/log/hilog/hilog.rar /data/log/hilog/*
hdc_std.exe file recv /data/log/hilog/hilog.rar .\

5.4.5、根据前面步骤抓取到的漏释放时间12:17:26,找到对应日志文件,根据日志梳理流程。确认ion内存漏释放时,camera底层库mmap函数和munmap函数未被执行,如下图:

image-20230706151004473

 

5.4.6、分析munmap函数和close函数的源码,发现munmap函数中做了对ion内存的释放操作,close函数没有释放ion内存的操作。在close函数里添加对未释放ion内存的检测以及释放后,测试OK。如下:

int ***V4l2AdapterImpl::close(int fd) {
  ......
  /*---start---新增代码如下:对ION内存进行检测并释放---start---*/
  int tmp = mPreviewHeapNum;
  for (int i = 0; i < tmp; i++) {
    if (mFullPathDataHeap[i]) {
      if (mFullPathDataHeap[i]->ion_heap) {
        delete mFullPathDataHeap[i]->ion_heap;
        mFullPathDataHeap[i]->ion_heap = NULL;
      }
      free(mFullPathDataHeap[i]);
      mFullPathDataHeap[i] = NULL;
      mPreviewHeapNum--;
    }
  }
  /*---end---新增代码如上:对ION内存进行检测并释放---end---*/
  ......
  return ret;
}

 

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐