hisi平台异常重启问题分析

article/2025/11/8 12:41:13

Hisi平台开发之异常重启问题分析

目录

1. 问题描述...................................................................................................................... 3

2. 问题跟踪排查............................................................................................................... 3

2.1 问题分析............................................................................................................. 3

2.2 问题拆解............................................................................................................. 3

4. 问题再分析.................................................................................................................. 6

5. 后记............................................................................................................................. 9

1. 问题描述

         海思平台开发过程中加载大特征值过程中,遇到系统没有任何征兆,直接重启现象

2. 问题跟踪排查

2.1 问题分析

设备在加载过程中,将系统的内存使用情况,串口日志,业务日志,kmsg等信息都调出来,观察现象发生时有无异常信息输出。

经过多次测试,发现加载过程中,确定除了内存不停下降,无任何异常信息。系统直接重启,组内讨论最终将该问题拆解为:

  1. 系统内存为何不停的下降
  2. 系统内存在剩余55M左右,为何会重

其中问题1,又分解为两部分,a、系统在加载特征值的过程中sdk消耗内存;b、sdk回调给设备消耗的内存。(隐去公司名称)

本文仅讨论分享问题1,至于问题2本身也是一个很有意义的问题,背后涉及的技术问题也值得关注,后续有时间再写。

分析拆解问题,将一个大的问题,划分为若干小的问题,再将小问题个个击破,最终得到大问题的解,是一个常用的手段。体现了计算机算法思想中的分而治之,是我们需要不断提高的能力。将问题1分解为a/b两部分后,就可以具体分析是哪里消耗的内存了。

2.2 问题拆解

将问题拆分为两部分后,先分析我们自己的内存消耗情况,钉钉SDK回调给我们特征值后,不加入内存,查看内存的消耗情况。注:此时特征值已经从云端拉下来存db,仅几百人,通过接口让dt_sdk不停触发回调加载特征值。这种测试条件下,惊奇的发现,内存不在不停的增加了。于是我们可以断定在md加载特征值的过程中不停的消耗内存。

新的问题来了,我们加载特征值的内存时预先申请好的,理论上,加载过程中,不会再消耗内存,但是我们测试过程中,却明显看到内存再不停的下降。关于查看内存的使用情况,可以使用 cat /proc/meminfo的输出信息中的MemAvailable,这个字段描述新进程可以使用的最大内存,其他各个字段的含义可以google 或者通过 man proc查看。Proc是内核和用户交互的重要窗口,很多重要的数据都可以通过proc打印出来。问题聚焦在我们加载特征值时候的内存使用情况分析。查看相关代码,

这个m_featureTable就是我们存特征值的地址,不知道你有没有发现问题。不错,memset的长度不对,只有指针的大小,32位系统占4个字节。于是我们修改这里memset的大小,期待问题得到解决,修改代码后,再次测试。问题没有如期得到解决,还是看到内存慢慢下降。于是分析陷入停滞,没有突破口。

于是我们又分析了单独调用xx公司拉取特征值这部分接口,查看内存消耗情况,xx公司在x86上也做过同样的事情,不错,在拉特征值的时候,xx公司sdk不停的消耗内存。内存消耗基本上定位在两个阶段,第一,xx公司从云端拉取到设备会消耗大量内存。第二,xx公司sdk加载给dev,dev加载过程中也在消耗大量内存。

2.3 内存管理及分配

    对于云端到xx公司sdk消耗的内存,只能由xx公司测分析。我们只能关注我们自己这一块内存的使用情况,为什么在加载特征值过程中,可用存不停的往下掉。       简单介绍下linux的内存管理:内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的,这样进程就可以很方便地访问虚拟内存。

虚拟地址空间的内部又被分为内核空间和用户空间两部分,地址空间的范围也不同。比如最常见的32位的虚拟地址空间:

简单介绍下用户态和内核态,这个描述的是,cpu运行的特权模式,不通的模式所拥有的权限是不通的,用户态模式访问的权限低,能做的事情就有限。进程在用户态时,只能访问用户空间内存;只有进入内核态后,才可以访问内核空间内存。虽然每个进程的地址空间都包含了内核空间,但这些内核空间,其实关联的都是相同的物理内存。这样,进程切换到内核态后,就可以很方便地访问内核空间内存。既然每个进程都有一个这么大的地址空间,那么所有进程的虚拟内存加起来,自然要比实际的物理内存大得多。所以,并不是所有的虚拟内存都会分配物理内存,只有那些实际使用的虚拟内存才分配物理内存,并且分配后的物理内存,是通过内存映射来管理的。内存映射,其实就是将虚拟内存地址映射到物理内存地址。为了完成内存映射,内核为每个进程都维护了一张页表,记录虚拟地址与物理地址的映射关系,如下图所示:

页表实际上存储在CPU的内存管理单元MMU中,这样,正常情况下,处理器就可以直接通过硬件,找出要访问的内存。而当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入内核空间分配物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。

内存分配与回收:

malloc()是C标准库提供的内存分配函数,对应到系统调用上,有两种实现方式,即brk()和mmap()。

对小块内存(小于128K),C标准库使用brk()来分配,也就是通过移动堆顶的位置来分配内存。这些内存释放后并不会立刻归还系统,而是被缓存起来,这样就可以重复使用。

而大块内存(大于128K),则直接使用内存映射 mmap() 来分配,也就是在文件映射段找一块空闲内存分配出去。

这两种方式,自然各有优缺点。

brk() 方式的缓存,可以减少缺页异常的发生,提高内存访问效率。不过,由于这些内存没有归还系统,在内存工作繁忙时,频繁的内存分配和释放会造成内存碎片。而 mmap() 方式分配的内存,会在释放时直接归还系统,所以每次 mmap 都会发生缺页异常。在内存工作繁忙时,频繁的内存分配会导致大量的缺页异常,使内核的管理负担增大。当这两种调用发生后,其实并没有真正分配内存。这些内存,都只在首次访问时才分配,也就是通过缺页异常进入内核中,再由内核来分配内存。对内存来说,如果只分配而不释放,就会造成内存泄漏,甚至会耗尽系统内存。所以,在应用程序用完内存后,还需要调用 free() 或 unmap() ,来释放这些不用的内存。

3 问题再分析

特征值内存申请了30k * 2KB = 60MB的内存,因此c库应该使用mmap的方式申请内存,而后调用memset初始化内存,此时内核应该会建立虚拟内存和物理内存的映射关系,再接着就可以正常使用这片内存了。但是我们看到的现象确实内存一点点往下掉,不是整片开好的内存。于是怀疑memset没有起作用,否则不会再使用的时候才分配内存。有个这个怀疑点,我们就可以写测试代码,验证刚才的逻辑了,测试代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

int main(int argc, char *argv[])

{

    int i = 0;

    int sum = 0;

    char *p = NULL;

    do

    {

        p = (char*)malloc (1024 * 1024 * 100);     

        if (p)

        {

            memset(p, 0, 1024* 1024 * 100);           

            //printf("malloc 1M suc, i:%d\n", i++);

        }

        else

        {

            printf("total malloc %dMB\n",i);

            break;

        }

    }while(0);

 

    for (i=0; i < 1024 * 1024 * 1024; i++)

    {

        sum += i;

    }

    printf("input someting quit\n");

    getchar();

    getchar();

    return 0;

}

 

就是一个分配内存,并memset,其他累和也是之前测试代码,不用关系。那么这段代码运行后,设备上的可用内存变化是什么情况呢?

编译如下:

arm-himix200-linux-gcc -o memTest0  mem.c

设备上运行 ./memTest0,发现分配出了内存。这个说明memset是生效的。

如果我们使用下面这个编译:

arm-himix200-linux-gcc -O2 -o memTest1  mem.c 

设备上运行 ./memTest1,发现没有分配出内存。这个说明memset是没有生效。

讲到这里结论应该很明显了,编译选项中的优化选项-O2 把memset给优化掉了。怎么确认我们的这个推测呢?我们可以使用objdump反汇编来查看最终的可执行文件。使用如下命令:

arm-himix200-linux-objdump -D memTest0 > ~/share/memTest_dump

arm-himix200-linux-objdump -D memTest1 > ~/share/memTest_dump_O2

比较dump信息:

 

很明显,O2优化后的dump没有调用memset了,所以虽然代码中调用了memset,由于开启o2编译优化,memset会被优化掉,使用时才真正分配内存。

4   后记

  1. 文章开始提到的系统直接重启原因分析
  2. 关于开启O2优化,及系统优化的问题

知识这东西就需要经常的核实和订正,尤其是从别人那听来的知识--卓克。

共勉

您的支持是最大的创作动力


http://chatgpt.dhexx.cn/article/60K0vyQR.shtml

相关文章

【HISI系列】之开发板调试基本知识

1. HISI 根文件系统简介 Linux 的目录结构的最顶层是一个被称为“ / ”的根目录。系统加载 Linux 内核之后&#xff0c;就会挂载一个设备到根目录上。存在于这个设备中的文件系统被称为根文件系统。所有的系统命令、系统配置以及其他文件系统的挂载点都位于这个根文件系统中。 …

HTTP Digest接入方式鉴权认证流程

HTTP Digest接入方式鉴权认证流程 一、摘要认证原理 摘要认证与基础认证的工作原理很相似&#xff0c;用户先发出一个没有认证证书的请求&#xff0c;Web服务器回复一个带有WWW-Authenticate头的响应&#xff0c;指明访问所请求的资源需要证书。但是和基础认证发送以Base 64编…

C++ libcurl Digest Auth

C libcurl Digest Auth postman操作如下&#xff1a; 附认证原理如下&#xff1a; MD5 md5; string HA1 md5("username:realm:password"); string HA2 md5("method:uri"); string response md5("HA1:nouce:nc:cnonce:qop:HA2"); 这里…

mysql sql语句digest收集与展示

1.前言 mysql慢查询&#xff0c;已经有现成的成熟的方案收集展示了&#xff1a;pt-query-digest结合box公司的anemometer&#xff0c;没用过的移步&#xff1a;《mysql慢查询可视化》&#xff08;本章内容需要提前了解anemometer&#xff09;。 但DBA们一定还遇到过这样的问题…

HTTP Digest authentication

什么是摘要认证 摘要认证&#xff08; Digest authentication&#xff09;是一个简单的认证机制&#xff0c;最初是为HTTP协议开发的&#xff0c;因而也常叫做HTTP摘要&#xff0c;在RFC2617中描述。其身份验证机制很简单&#xff0c;它采用杂凑式&#xff08;hash&#xff09…

配置Apache Digest认证

Apache常见的用户认证可以分为下面三种&#xff1a; 基于IP&#xff0c;子网的访问控制(ACL)基本用户验证(Basic Authentication)消息摘要式身份验证(Digest Authentication) 消息摘要式身份验证(Digest Authentication) Digest Authentication在基本身份验证上面扩展了安全…

http Digest认证计算方法整理

摘要认证及实现HTTP digest authentication - 简书 HTTP Basic和Digest认证介绍与计算 - 诸子流 - 博客园 不要不知道上面说的URI是什么意思啊 图解HTTP 第 8 章 确认访问用户身份的认证 - 简书8.1 何为认证 为了弄清究竟是谁在访问服务器&#xff0c;就得让对方的客户端自报家…

业务维度digest日志的记录与监控方案

需求 ​   为了满足从业务整体的维度 实现监控和链路复原&#xff0c;我们希望对于一个业务接口&#xff0c;记录一行请求日志&#xff0c;并通过某个 Unique Id&#xff08;如UserId、OrderId&#xff09;将多行日志关联起来&#xff0c;最终产出一批和业务强相关的数据&am…

java发起Digest Auth请求

常规认证方式 上代码&#xff1a; 需要的Maven <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5</version></dependency><dependency><groupId>org.…

认证学习3 - Digest摘要认证讲解、代码实现、演示

文章目录 Digest摘要认证 - 密文讲解&#xff08;Digest摘要认证&#xff09;实现&#xff08;Digest认证&#xff09;代码&#xff08;Digest认证&#xff09;代码&#xff08;Digest认证-客户端&#xff09;演示&#xff08;Digest认证-postman&#xff09; 认证大全&#xf…

HTTP的认证方式之DIGEST 认证(摘要认证)

核心步骤&#xff1a; 步骤 1&#xff1a; 请求需认证的资源时&#xff0c;服务器会随着状态码 401Authorization Required&#xff0c;返回带WWW-Authenticate 首部字段的响应。该字段内包含质问响应方式认证所需的临时质询码&#xff08;随机数&#xff0c;nonce&#xff09;…

Digest Auth 摘要认证

Digest Auth 摘要认证 1.非常规方式 转载&#xff1a;https://blog.csdn.net/qq_25391785/article/details/86595529 public static void postMethod(String url, String query) {try {CredentialsProvider credsProvider new BasicCredentialsProvider();credsProvider.setC…

digest鉴权

“摘要”式认证&#xff08; Digest authentication&#xff09;是一个简单的认证机制&#xff0c;最初是为HTTP协议开发的&#xff0c;因而也常叫做HTTP摘要&#xff0c;在RFC2671中描述。其身份验证机制很简单&#xff0c;它采用杂凑式&#xff08;hash&#xff09;加密方法&…

消息摘要(Digest),数字签名(Signature),数字证书(Certificate)是什么?

1. 消息摘要&#xff08;Digest&#xff09; 1. 什么是消息摘要&#xff1f; 对一份数据&#xff0c;进行一个单向的 Hash 函数&#xff0c;生成一个固定长度的 Hash 值&#xff0c;这个值就是这份数据的摘要&#xff0c;也称为指纹。 2. 摘要算法 常见的摘要算法有 MD5、SHA…

HTTP通讯安全中的Digest摘要认证释义与实现

摘要 出于安全考虑&#xff0c;HTTP规范定义了几种认证方式以对访问者身份进行鉴权&#xff0c;最常见的认证方式之一是Digest认证 Digest认证简介 HTTP通讯采用人类可阅读的文本格式进行数据通讯&#xff0c;其内容非常容易被解读。出于安全考虑&#xff0c;HTTP规范定义了几…

http协议之digest(摘要)认证,详细讲解并附Java SpringBoot源码

目录 1.digest认证是什么&#xff1f; 2.digest认证过程 3.digest认证参数详解 4.基于SpringBoot实现digest认证 5.digest认证演示 6.digest认证完整项目 7.参考博客 1.digest认证是什么&#xff1f; HTTP通讯采用人类可阅读的文本格式进行数据通讯&#xff0c;其内容非…

【WinRAR】WinRAR 6.01 官方最新简体中文版

WinRAR 6.01 官方简体中文商业版下载地址&#xff08;需要注册&#xff09;&#xff1a; 64位&#xff1a; https://www.win-rar.com/fileadmin/winrar-versions/sc/sc20210414/wrr/winrar-x64-601sc.exe https://www.win-rar.com/fileadmin/winrar-versions/sc/sc20210414/…

WinRAR命令行

基本使用 实践 将文件夹压缩到zip包 输入&#xff1a;文件夹如下&#xff0c;文件夹为class。 输出&#xff1a;classes.zip 指令如下&#xff1a; rar a classes.zip .\classes或者 WinRAR a classes.zip .\classes结果如下&#xff1a; PS C:\Users\liyd\Desktop\kuai…

WinRAR安装教程

文章目录 WinRAR安装教程无广告1. 下载2. 安装3. 注册4. 去广告 WinRAR安装教程无广告 1. 下载 国内官网&#xff1a;https://www.winrar.com.cn/ 2. 安装 双击&#xff0c;使用默认路径&#xff1a; 点击“安装”。 点击“确定”。 点击“完成”。 3. 注册 链接&#x…

WinRAR注册+去广告教程

1、注册 在WinRAR安装目录创建rarreg.key文件&#xff0c; 拷贝如下内容并保存&#xff1a; RAR registration data Federal Agency for Education 1000000 PC usage license UIDb621cca9a84bc5deffbf 6412612250ffbf533df6db2dfe8ccc3aae5362c06d54762105357d 5e3b1489e751c…