[摘]Android 系统重启原因分析

Android  2020年12月9日 pm7:51发布4年前 (2020)更新 城堡大人
142 0 0

前言

Android重启,这种影响使用的问题必须解决和找出原因。

正文

以下是摘抄文章内容,略有删减。

重启原因分类

  1. 上层造成重启
  1. kernel造成重启
  • 空指针
  • 非法地址
  1. kernel watchdog造成重启,原因不确定
  • 内存原因
  • nand驱动

log查看步骤及关键字

重启后的kernel.log或misc/cmdline.log

在log最前面,会有很长的一段,如:

 initrd=0x85500000,0x204229 apv="td860-user 4.1.2 MocorDroid4.1.2 eng..20131107.215135 test-keys" mem=512M loglevel=1 console=ttyS1,115200n8 init=/init mtdparts=sprd-nand:256k(spl),512k(2ndbl),256k(params),512k(vmjaluna),10m(modem),3840k(fixnv),3840k(backupfixnv),5120k(dsp),3840k(runtimenv),10m(boot),10m(recovery),250m(system),180m(userdata),20m(cache),256k(misc),1m(boot_logo),1m(fastboot_logo),3840k(productinfo),512k(kpanic) androidboot.mode=panic lcd_id=ID9816 lcd_base=8ff27000 CHR_STATE=0 ram=512M no_console_suspend boot_ram_log=0x8fe00000,0x80000 tdfixnv=0x89060000,0x40000 tdruntimenv=0x890a0000,0x60000 wfixnv=0x90440000,0x40000 wruntimenv=0x90480000,0x60000 productinfo=0x80490000,0x4000 androidboot.serialno=12345678912345 adc_cal=216338536,185339408 fgu_cal=186388584,159845904,7534 fgu_init=2805,7742

搜索

 androidboot.mode

看开机的模式,如果没有则默认为normal mode,正常开机;

上例中为panic,为kernel中出错导致的重启。

这个值是从ANA_REG_GLB_POR_RST_MONITOR位中获取到的值,每次获取完之后会置为0:

 rst_mode = ANA_REG_GET(ANA_REG_GLB_POR_RST_MONITOR);rst_mode &= 0x7FFF;ANA_REG_SET(ANA_REG_GLB_POR_RST_MONITOR, 0); //clear flag

这个值是重启前填入的,如HWRST_STATUS_PANIC、HWRST_STATUS_ALARM等。

重启后的last_kmsg log

此文件记录了重启前的kernel log,搜索

panic

确定问题发生在上层还是底层,如果有panic相关信息一般都是kernel造成的问题,如果有Restarting system则是上层造成的。

案例一:上层空指针引起的重启
0[ 83.522143] Restarting system with command 'special-systemserver-died'.0[ 83.900657] SPRD_WDT watchdog_feeder, margin=20, feed_period=3, sys_cnt = 862250[ 84.026350] sprd_set_reboot_mode:cmd=special-systemserver-died

此时是由于上层systemserver出了问题导致重启,查看重启方式是androidboot.mode=special,是system server挂掉引起的重启,看上去special方式启动都是上层引起的。

案例二:

【其他】手机处于待机状态长按Power键弹出POP选框不做任何操作还继续长按Power,手机会自动重启。

【预置条件】无

【操作步骤】手机处于待机状态长按Power键--弹出POP选框不做任何操作--还继续长按Power

【实际结果】手机会自动重启

【预期结果】应正常

【复现概率】Must

【备注说明】对比其他手机无此现象。

分析:last_kmsg中搜索到

 sprd_set_reboot_mode:cmd=panic

说明是kernel导致的重启,附件的log中还有

 !!!! trigger_watch_powerkey !!!! do emergency_restart

说明很可能是主动调用重启,在代码中搜索发现

 static void trigger_watch_powerkey(void *private){ unsigned long flags; local_irq_save(flags);#ifdef CONFIG_MAGIC_SYSRQ handle_sysrq('m'); handle_sysrq('w');#endif pr_warn("!!!! trigger_watch_powerkey !!!! do emergency_restart\n"); emergency_restart(); pr_err("%s should never reach here!\n", __func__);}

长按power键超过6秒时会调用此函数,使得手机重启,咨询展讯是为了调试定屏问题所增加的功能,量产时可以去除。

解决方法:代码中注释掉input_report_key_hook函数的调用,Makefile中不编译input-hook.o库。

案例三:

【无线热点】下拉状态栏,点击无线热点,手机自动重启

【预置条件】无

【操作步骤】下拉状态栏--多次点击无线热点

【实际结果】手机自动重启

【预期结果】无线热点正常打开和关闭

【复现概率】经常

分析:last_kmsg中搜索到

 Kernel panic - not syncing: Fatal exception

说明是kernel导致的重启,而且打印出堆栈信息判断应为WIFI问题,查看last_log中的kernel log,可能是soft_ap打开时失败。

 01-01 08:06:06.522 <4>[ 296.682000] thr_wait_for_2nd_eth_dev: sap_eth_sema timeout

解决方法:增加打开尝试次数为3次,减小打开失败概率。

查看重启前的android log

在Android log中,搜索关键字 died, 确认是否system server被杀,如果是查看具体原因。

案例四:开机动画过后手机自动重启

log最后显示

 I/Zygote ( 86): Exit zygote because system server (222) has terminated

原因是

 E/AndroidRuntime( 222): *** FATAL EXCEPTION IN SYSTEM PROCESS: android.server.ServerThread

ActivityManagerService.Java:4182中的空指针导致的,而前面还有一些空指针异常,第1个是

E/SystemServer( 222): java.lang.NullPointerExceptionE/SystemServer( 222): at android.sim.SimManagerService.<init>(SimManagerService.java:94)E/SystemServer( 222): at com.android.server.ServerThread.run(SystemServer.java:219)

SimManagerService 94行为

mContext.registerReceiver(mReceiver, filter);

可能是mContext空指针,而

  Context temp = null; try { temp = context.createPackageContext("com.android.settings", Context.CONTEXT_IGNORE_SECURITY); } catch (NameNotFoundException e) { e.printStackTrace(); }; mContext = temp;

所以createPackageContext可能创建失败导致,temp为null。再回到log

W/System.err( 222): android.content.pm.PackageManager$NameNotFoundException: Application package com.android.settings not found

证实了这一点, 搜索“com.android.settings”

E/PackageManager( 222): Package com.android.settings has no signatures that match those in shared user android.uid.system; ignoring!

发现初始化失败,可能是签名或share user id或是版本不匹配导致,导出Settings.apk,反编译并查看AndroidManifest.xml

 <manifest android:sharedUserId="android.uid.system" android:versionCode="15" android:versionName="4.0.3-eng..20130516.160103" package="com.android.settings" coreApp="true" xmlns:android="http://schemas.android.com/apk/res/android">

 android:versionName="4.0.3-eng..20130516.160103"

此信息显示Settings为20130516号编译的版本,与测试提供的信息20130627版本不匹配,最终原因是驱动下载了差异较大的boot.img导致。

解决方法:下载20130516版本的boot.img即可恢复并正常开机。

上层watchdog产生的重启,查看重启前的traces.txt

软件framework层的WatchDog主要作用:接收系统内部reboot请求,重启系统;监护SystemServer进程,防止系统死锁;每30秒检查一次。

在android log, 关键字:WATCHDOG KILLING SYSTEM PROCESS

确认是否是watchdog造成的重启。如果是,则要查看重启前的traces.txt,检查下面3项:

  • 确认是否有kernel stack
  • 关键字'held', 找到阻塞源头
  • 不能被阻塞的线程:WindowManager、ActivityManager、PowerManager、ServerThread
案例五:上层AMS、WMS死锁导致watchdog重启
"Thread-304" prio=5 tid=4 MONITOR| group="main" sCount=1 dsCount=0 obj=0x41c16ef8 self=0x69b8a8| sysTid=3040 nice=0 sched=0/0 cgrp=[no-cpu-subsys] handle=7056472| schedstat=( 0 0 0 ) utm=0 stm=0 core=1at com.android.server.wm.WindowManagerService.resumeKeyDispatching(WindowManagerService.java:~6346)- waiting to lock <0x41738e80> (a java.util.HashMap) held by tid=12 (android.server.ServerThread)at com.android.server.am.ActivityRecord.resumeKeyDispatchingLocked(ActivityRecord.java:554)at com.android.server.am.ActivityStack$myThread.run(ActivityStack.java:4314)"android.server.ServerThread" prio=5 tid=12 MONITOR| group="main" sCount=1 dsCount=0 obj=0x4154a9a8 self=0x32e200| sysTid=275 nice=-2 sched=0/0 cgrp=[no-cpu-subsys] handle=3607224| schedstat=( 0 0 0 ) utm=830 stm=262 core=1at com.android.server.am.ActivityManagerService.getTasks(ActivityManagerService.java:~5389)- waiting to lock <0x41555738> (a com.android.server.am.ActivityManagerService) held by tid=4 (Thread-304)

由上面log可知AMS和WMS发生了死锁,导致了watchdog重启。

重启后kernel.log、misc/last_kmsg、dump文件

内核或hal层出现的错误有很多,这里主要将oops或有堆栈信息的问题分析方法,主要分为3类:

一个.so或多个.so文件引起的问题,可能产生的问题并不是重启

案例六:libwebcore.so导致浏览器强关(内存地址+so)

 15:50:05.633 I DEBUG : pid: 7662, tid: 7677 >>> com.android.browser <<<15:50:05.633 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0000000815:50:05.673 I DEBUG : #00 pc 000b852a /system/lib/libwebcore.so15:50:05.673 I DEBUG : #01 pc 000b887c /system/lib/libwebcore.so15:50:05.673 I DEBUG : #02 pc 000b6428 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #03 pc 00218852 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #04 pc 000be9c4 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #05 pc 000beaae /system/lib/libwebcore.so15:50:05.673 I DEBUG : #06 pc 000bf1e8 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #07 pc 000a9242 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #08 pc 000a7f6a /system/lib/libwebcore.so15:50:05.673 I DEBUG : #09 pc 000a71a8 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #10 pc 000aac4a /system/lib/libwebcore.so15:50:05.673 I DEBUG : #11 pc 000aaf06 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #12 pc 000b3304 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #13 pc 000b33fa /system/lib/libwebcore.so15:50:05.673 I DEBUG : #14 pc 00093230 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #15 pc 001e95aa /system/lib/libwebcore.so15:50:05.673 I DEBUG : #16 pc 001da83e /system/lib/libwebcore.so15:50:05.673 I DEBUG : #17 pc 001d6544 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #18 pc 001d658c /system/lib/libwebcore.so15:50:05.673 I DEBUG : #19 pc 001644ac /system/lib/libwebcore.so15:50:05.673 I DEBUG : #20 pc 00253ba8 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #21 pc 002dee9c /system/lib/libwebcore.so15:50:05.673 I DEBUG : #22 pc 002e4f24 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #23 pc 002e51f2 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #24 pc 0033ac62 /system/lib/libwebcore.so15:50:05.673 I DEBUG : #25 pc 0033acc8 /system/lib/libwebcore.so

这是从android log中截取的信息,原理是一样。这种log可以通过addr2line工具进行反编译,addr2line位于目录

/prebuilt/Linux-x86/toolchain/arm-eabi-4.4.3/bin

命令是

 addr2line -e -f libwebcore.so 000b852a

libwebcore.so是带符号表的so,位于

/out/target/product/sp8830ec/symbols/system/lib,000b852a

是对应的出错地址

一个或多个so引起的问题,还可以从网上找个脚本,把堆栈信息单独保存到文件中,然后使用脚本反编译,会把每个地址对应的源函数反编译出来,网上有很多这里就不贴出脚本了。

hal层即非内核层出现地址错误产生的重启问题
案例七:驱动去除光感后开机不断重启(so+函数名+偏移地址)
 Fatal signal 11 (SIGSEGV) at 0x00000001 (code=1), thread 456 (system_server)I/DEBUG ( 138): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***I/DEBUG ( 138): Build fingerprint: 'Lenovo/A388t/A388t:4.1.2/MocorDroid4.1.2/A388t_S161_131112.20131121:user/release-keys'I/DEBUG ( 138): pid: 456, tid: 456, name: system_server >>> system_server <<<I/DEBUG ( 138): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000001I/DEBUG ( 138): r0 00000001 r1 00000001 r2 00000001 r3 5a07d004I/DEBUG ( 138): r4 5aedd2c0 r5 403ff19c r6 5aedd2c4 r7 00000001I/DEBUG ( 138): r8 5a07d004 r9 00000088 sl 00000003 fp 5aedd2b8I/DEBUG ( 138): ip 40317e94 sp bea80548 lr 4030e6a1 pc 40211048 cpsr 20000010……I/DEBUG ( 138): backtrace:I/DEBUG ( 138): #00 pc 00017048 /system/lib/libc.so (strlen+16)I/DEBUG ( 138): #01 pc 0000f69d /system/lib/libutils.so (android::String8::setTo(char const*)+8)I/DEBUG ( 138): #02 pc 0001e7d3 /system/lib/libgui.so (android::Sensor::Sensor(sensor_t const*)+38)I/DEBUG ( 138): #03 pc 0000e5af /system/lib/libsensorservice.so (android::HardwareSensor::HardwareSensor(sensor_t const&)+70)I/DEBUG ( 138): #04 pc 0000f78f /system/lib/libsensorservice.so (android::SensorService::onFirstRef()+110)I/DEBUG ( 138): #05 pc 0000edd5 /system/lib/libutils.so (android::RefBase::incStrong(void const*) const+38)I/DEBUG ( 138): #06 pc 000010d1 /system/lib/libsystem_server.soI/DEBUG ( 138): #07 pc 000011eb /system/lib/libsystem_server.so (system_init+242)……D/Zygote ( 140): Process 456 terminated by signal (11)I/Zygote ( 140): Exit zygote because system server (456) has terminated

很明显是Zygote初始化时system server访问错误地址00000001导致初始化失败产生的重启,堆栈信息如下:

#00 pc 00017048 /system/lib/libc.so (strlen+16)#01 pc 0000f69d /system/lib/libutils.so (android::String8::setTo(char const*)+8)#02 pc 0001e7d3 /system/lib/libgui.so (android::Sensor::Sensor(sensor_t const*)+38)#03 pc 0000e5af /system/lib/libsensorservice.so (android::HardwareSensor::HardwareSensor(sensor_t const&)+70)#04 pc 0000f78f /system/lib/libsensorservice.so (android::SensorService::onFirstRef()+110)

1).看上去虽然栈顶是/system/lib/libc.so (strlen+16)时出现的错误,但实际是传过去的参数有问题,问题应是从 android::SensorService::onFirstRef()+110 这里开始;

2).找到SensorService.cpp中onFirstRef函数,出错是在

registerSensor( new HardwareSensor(list[i]) );

,即初始化HardwareSensor(list[i])出现的问题,可以发现仍然是函数参数地址不正确引起的;

3).而list是

ssize_t count = dev.getSensorList(&list);

得到的,具体调用的是sensors_module_t mSensorModule的getSensorList;

4).mSensorModule是通过

status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule);

进行初始化的,hw_get_module则是hardware中通过SENSORS_HARDWARE_MODULE_ID加载对应so文件的函数,即sensor.xxxx.so

5).而sensor.xxxx.so是/device/sprd/common/libs/libsensors_sprd/模块生成的文件,因此这个getSensorList实际是通过/device/sprd/common/libs/libsensors_sprd/sensors.cpp中sensors__get_sensors_list得到的,查看错误log前面的信息:

D/Sensors ( 456): BmaSensors=1; 1D/Sensors ( 456): SensorHQALSPS: open_device /dev/alspsD/Sensors ( 456): alsps Sensor: get name:: (ft6306_ps)D/Sensors ( 456): SensorHQALSPS: getName = ft6306_psD/Sensors ( 456): PnumSensors=3; 2D/Sensors ( 456): activate handle=0; drv=0D/Sensors ( 456): BmaSensor: mEnabled = 0, enabled = 0.D/Sensors ( 456): activate handle=4; drv=1D/Sensors ( 456): SensorHQALSPS::setEnable=0= en=0; newState=0; what=1; mEnabled=0D/Sensors ( 456): HQALSPS ---Proximity::HQALSPS_IOCTL_PROX_OFF=== err=0D/Sensors ( 456): SensorHQALSPS::setEnable=1= en=0; newState=0; what=1; mEnabled=0

6).再结合问题去除光感后,手机不断重启,所以可能是

D/Sensors ( 456): PnumSensors=3; 2

中,光感、接近传感器的numSensors有问题,而:

mSensors[pls] = new SensorHQALSPS();numSensors += mSensors[pls]->populateSensorList(sSensorList + numSensors);……ALOGD("PnumSensors=%d; %d", numSensors, PlsSensor::numSensors);

 populateSensorList返回的就是AlspsSensor.h定义的numSensors,值为2:

 enum{ Light = 0, Proximity = 1, numSensors};

所以最后修改为:

enum{ Proximity = 0, numSensors};
linux内核引起的Oops问题

对Linux内核来说,Oops就意外着内核出了异常,此时会将产生异常时CPU的状态,出错的指令地址、数据地址及其他寄存器,函数调用的顺序甚至是栈里面的内容都打印出来,然后根据异常的严重程度来决定下一步的操作:杀死导致异常的进程或者挂起系统。

最典型的异常是在内核态引用了一个非法地址,通常是未初始化的野指针Null,这将导致页表异常,最终引发Oops。分析错误原因的原理同第1种问题,vmlinux相当于so的合集,也是通过工具反编译找到对应的汇编行,同时查看对应的函数分析原因,这种问题往往比较复杂后面会单独写文档总结分析方法。

kernel watchdog造成重启

原因不确定,可能是内存原因、nand驱动。

参考文章

  1. Android 系统重启原因分析

 历史上的今天

  1. 2023: Service的Context介绍(0条评论)
  2. 2022: Android设置语言偏好后应用没有获取对设置的语言(0条评论)
  3. 2021: Android TV 应用中焦点的简单介绍(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

adb push有中文名的apk或者路径会出现名字不全

前言最近在调试时,push的apk目录中带有中问题,就存在push的apk后缀丢失正文偶然apk中带有中文或者存在的路径中带有中,由于疏忽,push后发现apk没有正常启动,最后发现,push的文件存在问题。如下。adb push Desktop\中国125la.apk /sdcard...

Android Studio工程中.idea没有*.iml文件

前言我使用其他同事电脑时,Android Studio(Android Studio Dolphin | 2021.3.1 Patch 1)的版本新建的工程中.idea目录没有对应module和*.iml。百度或谷歌后解决了。记录一下,方便自己查阅。正文解决这个问题很简单,就是Androi...

白岩松:幸福在哪里

一走在人群中,我习惯看一看周围人的手腕,那里似乎藏着一个属于当代中国人的内心秘密,从不言说,却日益增多。越来越多的人,不分男女,会戴上一个手串,这其中,不乏有人仅仅是为了装饰;更多的却带有祈福与安心的意味,这手串停留在装饰与信仰之间,或左或右。这其中,是怎样的一种相信或怎样的一种抚慰?又或者,来...

Android高版本getDrawable(int id)废弃后的替代方法

前言在Android 高版本上使用getDrawable(int id)时,如下,有提示使用的这个方法废弃了 mIvAlbum.setBackground(getResources().getDrawable(R.drawable.music_album_unknown));点进入源...

Application的Context介绍

前言对于Application,Activity和Service这几个类,我们是很[熟悉]的。确实[熟悉],作为App开发这基本都要面对这几个类。比较好奇的朋友会发现,他们都拥有Context,但他们的Context有似乎有一点点的不同。今天有空,根据网上大佬的步伐,在这里简单记录一下。正文...

C语言之指针数组和数组指针

前言简单记录一下指针数组和数组指针之间的区别。正文由于很容易搞混,因此这里做一下记录。指针数组指针数组是指具有若干个相同存储类型和数据类型的[指针变量]构成的组合。指针数组的一般形式:存储类型 数据类型 * 指针数组名 [大小]//指针数组,类型是int * 所以叫int型指...