KE之undefinded instruction问题记录

1. undefined instruction 具体是什么

1.1 分类

在android操作系统中根据异常发生层次不同,划分为:KE、NE、JE,另外还有HWT、SWT、ANR等几个类型是不同的层次中对于长时间不响应的case划分了类别;
这里主要为记录KE问题中Undefined Instruction问题:预取指令异常
计算机的操作可以被分为两类:1. 取数据;2. 取指令,则undefined instruction是其中的取指令异常;
异常分类
此异常是在CPU的硬件实现中已经可以被判断到,并且可以在kernel中定义了异常向量的处理函数,则在执行的指令并非CPU可以识别的情况时就会跳转到对应的处理函数中进行,目前对于此部分的处理主要是:收集此时堆栈中的信息,并将此部分数据保存到debug信息中,根据系统中配置的不同可能会hang在这里或者重启,这里重启有两种可能的情况:1. handle函数中调用了重启的接口;2. 此CPU hang住不会接收喂狗信息,触发到HWT重启;

1.1.1 armV8 体系结构的异常级别划分:

armv8的异常处理逻辑

1.2 instruction 原理性说明

首先show一张图:
在这里插入图片描述

  1. instruction的概念:
    1. CPU被设计为RISC(ARM)和CISC(X86)两种类型的指令集,分别针对于低功耗和高性能;
    1. RISC偏向于处理简单命令,即经常使用的指令,对于不常使用的指令通过组合简单指令来实现,对于特殊命令,性能低,单元电路少,所以功耗低;
    2. CISC偏向于处理复杂命令,所有指令都有实现,对存储器的操作可能性多,所以对于特殊指令性能会高,但是单元电路很多,所以整体功耗会高;
    2. 所有instruction的实现即CPU中根据指令集实现的逻辑电路,也就是指令(2进制编码)会在CPU中被翻译为电信号在逻辑电路中执行;
    2. 指令集中有哪些内容:
    TBD,就不一一列举了,可以去arm官网下载文档学习
    4. 异常触发:
    1. 指令集规定了指令的范围,所以不再这个范围内的值,CPU没有对应的逻辑电路,无法执行,即会被CPU 硬件电路判断为未定义的指令;[HW]
    2. CPU中定义了多种异常,在触发此类异常时,会进入异常向量表中所存放的handle函数处理;[汇编]
    3. 通过异常向量表,此类问题会进入do_unfi_abort进行处理,则至此进入kernel中的软件处理流程;[kernel]

aarch 64中定义的异常:
aarch64异常

2. 从过程分析有哪些可能性

所谓指令是存储在emmc中image的code段,在系统启动的时候被加载到内存,在程序运行到的时候load到CPU寄存器中解析使用;

  1. emmc中数据即被损坏,导致读取到数据异常,此种情况的话,为某种条件下必现,高概率为系统无法启动;
    • dump emmc中数据与烧录image做对比;
    • dump emmc中数据dd操作到另外的机器上相同方法测试;
    • 升级后可恢复;
  2. PC指针跑飞,从内存中取指令出现问题:
    • PC指针导致跑到数据段,取出的内容无法被解析为指令;
    • PC指针仍在code段,code段末尾为部分data数据,取出内容无法被解析为指令;
      一般来说,计算pc指针的位置就可以确认是否在code段,想要分辨是否跑飞则比较难,需要逐一做对比;
  3. PC指针正常,取出的数据与内存中值不同,一般怀疑为cache中出现问题,这种一般为Icache;
    • SOC Icache损坏,表现为bit 反转,则随机出现各种崩溃,且都为undefined instruction;
    • 由于环境因素导致HW取数据过程中出现某一个bit的偏转,低概率偶现;
      从过程来看基本上就上述几种类型,不过一般来讲此类异常相对于data abort还是比较少见啦;

3. 分析方法以及工具

  1. vmlinux 即符号库,用于对照是否机器内数据被破坏;
  2. readelf、addr2line、objdump等寄存器地址对应工具;
  3. trace32、gdb 主要用于模拟案发现场与vmlinux做对比;
3.1 实例分析(不典型)
3.1.1 问题

客户压测过程中偶现一次异常重启,重启后发现异常处理机制有抓取到一次KE

3.1.2 log

<0>[ 7232.602738]-(0)[349:logd.writer]Internal error: undefined instruction: 0 [#1] PREEMPT SMP
<6>[ 7232.603835]-(0)[349:logd.writer]disable aee kernel api
<5>[ 7232.604413]-(0)[349:logd.writer]Kernel Offset: 0x13c1c00000 from 0xffffff8008000000
<4>[ 7232.605590]-(0)[349:logd.writer]Modules linked in: usb_f_ean ffffffa665e29000 (null) 24576 0 wlan_drv_gen4m ffffffa665e39000 (null) 1929216 0 (O) wmt_chrdev_wifi ffffffa665e31000 (null) 28672 0 (O) gps_drv ffffffa665de1000 (null) 61440 0 (O) fmradio_drv ffffffa665dfd000 (null) 176128 0 (O) bt_drv ffffffa665df2000 (null) 32768 0 (O) wmt_drv ffffffa665cbd000 (null) 1191936 0 (O) fpsgo ffffffa665cb5000 (null) 16384 0 (O)
<5>[ 7233.612604]-(0)[349:logd.writer]Non-crashing CPUs did not react to IPI
<4>[ 7233.613485]-(0)[349:logd.writer]CPU: 0 PID: 349 Comm: logd.writer Tainted: G W O 4.9.117 #1
<4>[ 7233.614692]-(0)[349:logd.writer]Hardware name: AC8257V/WAB (DT)
<4>[ 7233.615478]-(0)[349:logd.writer]task: ffffffd2b962b000 task.stack: ffffffd2b9648000
<4>[ 7233.616492]-(0)[349:logd.writer]PC is at core_sys_select+0x8/0x3b4
<4>[ 7233.617310]-(0)[349:logd.writer]LR is at SyS_pselect6+0x214/0x418
<4>[ 7233.618115]-(0)[349:logd.writer]pc : [] lr : [] pstate: 80400145
<4>[ 7233.619297]-(0)[349:logd.writer]sp : ffffffd2b964bc70
<4>[ 7233.619972]-(0)[349:logd.writer]x29: ffffffd2b964beb0 x28: 0000000000000000
<4>[ 7233.620645]-(0)[349:logd.writer]x27: ffffff93caa22000 x26: 0000000000000048
<4>[ 7233.621317]-(0)[349:logd.writer]x25: 0000000000000000 x24: 0000000000000000
<4>[ 7233.621989]-(0)[349:logd.writer]x23: 0000000000000014 x22: 0000007cc1fff3a8
<4>[ 7233.622661]-(0)[349:logd.writer]x21: 0000000000000000 x20: 0000000000000000
<4>[ 7233.623333]-(0)[349:logd.writer]x19: 0000000000000000 x18: 0000007cc1ffd4da
<4>[ 7233.624005]-(0)[349:logd.writer]x17: 0000007cc29eb868 x16: ffffff93c9e3c388
<4>[ 7233.624677]-(0)[349:logd.writer]x15: 0000000000000000 x14: 0000007cc1600000
<4>[ 7233.625350]-(0)[349:logd.writer]x13: 00000000000c8a7f x12: 0000007cc24af270
<4>[ 7233.626022]-(0)[349:logd.writer]x11: 0000000000000000 x10: 0000000000000001
<4>[ 7233.626694]-(0)[349:logd.writer]x9 : 0000000000000002 x8 : 0000000000040975
<4>[ 7233.627365]-(0)[349:logd.writer]x7 : 0000ffffffffffff x6 : 0000000000000000
<4>[ 7233.628036]-(0)[349:logd.writer]x5 : 0000000000000000 x4 : 0000000000000000
<4>[ 7233.628709]-(0)[349:logd.writer]x3 : 0000000000000000 x2 : 0000000000000000
<4>[ 7233.629381]-(0)[349:logd.writer]x1 : 0000007cc1fff3a8 x0 : 0000000000000014
<4>[ 7233.630055]-(0)[349:logd.writer]
<4>[ 7233.630055]PC: 0xffffff93c9e3bdb8:

  1. Internal error: undefined instruction: 0 [#1] PREEMPT SMP 说明是undefined instruction
  2. 几个关键的寄存器:pc : [] lr : []
    • 通过pc指针和offset做计算可以得到vmlinux的逻辑地址 ffffff93c9e3be38 减去0x13c1c00000 得到的是FFFFFF800823BE38
    • 在vmlinux中搜索该地址,得到的code为:a91667fa
      vmlinux- 同过trace32解析minidump数据,该部分code为:
      coredump数据
      则说明:1. 上述PC指针位置在code段;2. 该部分数据没有被破坏;
      所以怀疑为在从dram中取到寄存器的过程中出现问题,即Icache中出现bit 反转这种可能性;
      由于没有dump出来Icache内容,所以无法直接判断;

而且由于此问题偶现,至今只出现一次,所以怀疑为受环境影响出现的取指令过程中出现异常的case,可能将会是一个无解之谜了;

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值