有台手机出现频繁上层重启问题,开机后不操作,放在桌子上不动,过一会就会发生FW重启,然后重复,查看log,发现是发生了system_server的NE问题,从Log看如下:
[log analysis]
01-27 11:41:19.553 5376 5376 F DEBUG : pid: 1404, tid: 2453, name: Binder:1404_7 >>> system_server <<<
01-27 11:41:19.554 5376 5376 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x11
01-27 11:41:19.554 5376 5376 F DEBUG : x0 0000000070708298 x1 0000000013418d00 x2 0000000000000008 x3 0000000013418d00
01-27 11:41:19.554 5376 5376 F DEBUG : x4 0000000000000007 x5 0000000000000003 x6 0000007f6ac3ddc0 x7 0000007f00000001
01-27 11:41:19.554 5376 5376 F DEBUG : x8 0000000000000001 x9 0000000000000000 x10 0000000000000000 x11 0000000000000000
01-27 11:41:19.554 5376 5376 F DEBUG : x12 0000000000000001 x13 00000000ffffffff x14 00000000001f8398 x15 2e8ba2e8ba2e8ba3
01-27 11:41:19.554 5376 5376 F DEBUG : x16 0000007f73d42140 x17 0000007f9c20b168 x18 0000000000000011 x19 0000007f7cef1a00
01-27 11:41:20.275 5376 5376 F DEBUG : backtrace:
01-27 11:41:20.275 5376 5376 F DEBUG : #00 pc 00000000005fe958 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.System.arraycopy+4)
01-27 11:41:20.275 5376 5376 F DEBUG : #01 pc 0000000002282c94 /system/framework/arm64/boot-framework.oat (offset 0x1712000) (android.util.ArrayMap.removeAt+816)
01-27 11:41:20.275 5376 5376 F DEBUG : #02 pc 00000000018b8958 /system/framework/arm64/boot-framework.oat (offset 0x1712000) (android.app.ResourcesManager.applyConfigurationToResourcesLocked+1204)
01-27 11:41:20.276 5376 5376 F DEBUG : #03 pc 00000000017d40a8 /system/framework/arm64/boot-framework.oat (offset 0x1712000) (android.app.ActivityThread.applyConfigurationToResources+100)
01-27 11:41:20.276 5376 5376 F DEBUG : #04 pc 000000000116d994 /system/framework/oat/arm64/services.odex (offset 0xea1000)
因为crash发生在oat文件里面,所以用下面的命令把oat文件dump出来,先查看下汇编代码:
adb shell oatdump --oat-file= /system/framework/arm64/boot.oat > oatdump_boot.txt
adb shell oatdump --oat-file= /system/framework/arm64/boot-framework.oat > oatdump_boot-framework.txt
从dump出来的文件里面可以找到crash的地方:
8: void java.lang.System.arraycopy(int[], int, int[], int, int) (dex_method_idx=3466)
CODE: (code_offset=0x005fd954 size_offset=0x005fd950 size=1312)...
0x005fd954: d1400bf0 sub x16, sp, #0x2000 (8192)
0x005fd958: b940021f ldr wzr, [x16] //crash this line
ldr wzr, [x16] 命令是将x16寄存器里面地址的内容保存到wzr寄存器里面,但x16寄存器里面的地址现在是0x11,这显然不是一个正确的内存地址,所以报错了。
但奇怪的地方是,从debug log里面打印出来的信息来看,x16寄存器里面的值应该是0000007f73d42140,而不是0x11,这就很奇怪了,理论上这两个地方打印出来的寄存器内容应该是一样的才对。
因为该问题很容易复现,重新抓取了两份log来查看,内容分别如下:
log1:
01-27 14:55:29.967 6412 6412 F DEBUG : pid: 1403, tid: 1751, name: NetdConnector >>> system_server <<<
01-27 14:55:29.967 6412 6412 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1
01-27 14:55:29.967 6412 6412 F DEBUG : x12 0000000000003000 x13 0000000000000006 x14 0000000000000000 x15 002bfb4b19459e10
01-27 14:55:29.968 6412 6412 F DEBUG : x16 0000007f8208ec80 x17 000000000025dc3b x18 0000000000000001 x19 0000007f8812a000
01-27 14:55:29.968 6412 6412 F DEBUG : x20 0000007f82a61268 x21 0000000013446f90 x22 0000000013aa1aa8 x23 00000000705c0ca8
01-27 14:55:30.654 6412 6412 F DEBUG :
01-27 14:55:30.654 6412 6412 F DEBUG : backtrace:
01-27 14:55:30.654 6412 6412 F DEBUG : #00 pc 00000000005e6ed8 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.String.format+4)
01-27 14:55:30.654 6412 6412 F DEBUG : #01 pc 00000000022984e0 /system/framework/arm64/boot-framework.oat (offset 0x1712000) (android.util.LocalLog.log+364)
01-27 14:55:30.654 6412 6412 F DEBUG : #02 pc 000000000100fc00 /system/framework/oat/arm64/services.odex (offset 0xea1000)
in oatdump_boot.txt:
21: java.lang.String java.lang.String.format(java.lang.String, java.lang.Object[]) (dex_method_idx=3174)
CODE: (code_offset=0x005e5ed4 size_offset=0x005e5ed0 size=188)...
0x005e5ed4: d1400bf0 sub x16, sp, #0x2000 (8192)
0x005e5ed8: b940021f ldr wzr, [x16] //crash at this code
log 2:
01-27 19:19:47.938 6130 6130 F DEBUG : pid: 1416, tid: 1448, name: android.bg >>> system_server <<<
01-27 19:19:47.938 6130 6130 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1
01-27 19:19:47.939 6130 6130 F DEBUG : x12 0000007f6f2a7860 x13 0041004c0041005f x14 0057005f004d0052 x15 002da0e95094197b
01-27 19:19:47.939 6130 6130 F DEBUG : x16 0000007f6f2a5920 x17 0000007f77da8578 x18 0000000000000001 x19 0000007f770b7600
01-27 19:19:47.939 6130 6130 F DEBUG : x20 0000000013b93910 x21 00000000001b7740 x22 00000000001b773f x23 0000000000000040
01-27 19:19:48.129 6130 6130 F DEBUG :
01-27 19:19:48.129 6130 6130 F DEBUG : backtrace:
01-27 19:19:48.129 6130 6130 F DEBUG : #00 pc 00000000006b2df8 /system/framework/arm64/boot.oat (offset 0x54e000) (java.util.Random.next+4)
01-27 19:19:48.129 6130 6130 F DEBUG : #01 pc 00000000006b3570 /system/framework/arm64/boot.oat (offset 0x54e000) (java.util.Random.nextInt+236)
01-27 19:19:48.129 6130 6130 F DEBUG : #02 pc 0000000000ee8e00 /system/framework/oat/arm64/services.odex (offset 0xea1000)
in oatdump_boot.txt:
23: int java.util.Random.next(int) (dex_method_idx=13325)
CODE: (code_offset=0x006b1df4 size_offset=0x006b1df0 size=232)...
0x006b1df4: d1400bf0 sub x16, sp, #0x2000 (8192)
0x006b1df8: b940021f ldr wzr, [x16] //crash at this code
可以看到,问题都是出现在取x16寄存器的地址的内容上,并且crash的地址和debug log打印出来的x16寄存器的值里面的地址都不一样,所以可以初步判断,这个问题应该不是由软件引起的。
【Soluiton】
更换了手机的内存后,该问题没有再复现了。