Android 平台如何排查内存被踩问题

当遇到内存被踩问题时,如何去分析呢?

  • 方法1:使用ASAN版本来打,具体方法可以参考:高通平台如何打开HWASAN
  • 方法2:将被踩的这块内存保护起来,设置为ready only

通过mprotect定位谁在踩这块内存

下面重点介绍下方法2的具体实现,假设CSLMessage这个结构体里面的某个成员变量值被踩了。

第1步:申请以Page(4KB)对齐的一块Buffer

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <sys/mman.h>

CSLMessage *                pNewCSLMessage;
int pagesize = sysconf(_SC_PAGE_SIZE);
char * buffer = NULL;
if (pagesize == -1) {
    CAMX_LOG_ERROR(CamxLogGroupCSL, "xxxxxx sysconf failed");
    return result;
}
buffer = (char *)memalign(pagesize, sizeof(CSLMessage));
pNewCSLMessage = reinterpret_cast<CSLMessage *>(buffer);

第2步:对CSLMessage进行修改,然后通过mprotect将CSLMessage设置为只读

pNewCSLMessage->type                                  = CSLMessageTypeFrame;
pNewCSLMessage->message.frameMessage.requestID        = pMessage->u.frame_msg.request_id;
pNewCSLMessage->message.frameMessage.frameCount       = pMessage->u.frame_msg.frame_id;
pNewCSLMessage->message.frameMessage.timestamp        = pMessage->u.frame_msg.timestamp;
pNewCSLMessage->message.frameMessage.link_hdl         = pMessage->u.frame_msg.link_hdl;
pNewCSLMessage->message.frameMessage.timestampType    = CSLTimestampTypeMono;
pNewCSLMessage->message.frameMessage.bNotify          = TRUE;
if (mprotect(buffer, pagesize, PROT_READ) == -1)
{
    CAMX_LOG_ERROR(CamxLogGroupCSL, "xxxxxx set one page as read only failed;");
}
// 如果要修改为可读写,则执行下面的代码
// if (mprotect(buffer, pagesize, PROT_READ|PROT_WRITE) == -1) {
//    CAMX_LOG_ERROR(CamxLogGroupCSL, "xxxxxx set one page as write prot failed;");
//}

这样就将CSLMessage这块buffer保护起来了,当有人来修改CSLMessage buffer的内容时会直接发生异常,通过异常我们就可以定位是谁在踩这块内存。

CPU 缓存导致的数据的不一致性

有时候,通过HWASAN或mprotect方法还是无法定位到是谁对某个变量进行修改了,这时候可以考虑是否是因为CPU 缓存导致的数据不一致,可以尝试用volatile来修饰该变量,如:

volatile CSLMessage *                pNewCSLMessage;

关于volatile的说明,请参阅:C语言 volatile 这篇文章。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程