Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1318580
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: Android平台

2016-05-31 11:06:52

1. 开机时若是卡在开机第一帧,就应该抓取串口log,若是在preloader/lk阶段,MTK平台是默认打印的,是可以直接打印出来的,若是卡在kernel阶段就比较麻烦一些,必须在lk中将串口log开启后才能抓取到kernellog
2. lk开机串口log方式:
aops/bootable/bootloader/lk/app/mt_boot/mt_boot.c
#ifdef USER_BUILD
        sprintf(cmdline,"%s%s",cmdline," printk.disable_uart=1");
#else
        sprintf(cmdline,"%s%s",cmdline," printk.disable_uart=0 ddebug_query=\"file *mediatek* +p ; file *gpu* =_\"");
#endif
共有两个地方需要修改,修改为如下信息:
#if  0 //def USER_BUILD
        sprintf(cmdline,"%s%s",cmdline," printk.disable_uart=1");
#else
        sprintf(cmdline,"%s%s",cmdline," printk.disable_uart=0 ddebug_query=\"file *mediatek* +p ; file *gpu* =_\"");
#endif

3. 抓取到串口log后看看kernel是否启动完成,可以从正常机器中查看/proc/bootprof,举例如下:
root@HWTIT-L6735:/ # cat /proc/bootprof                                       
----------------------------------------
0        BOOT PROF (unit:msec)
----------------------------------------
      4929        : preloader
      4281        : lk
       195        : lk->Kernel
----------------------------------------
      1515.397537 : Kernel_init_done
      2060.041845 : INIT: on init start
      2072.401999 : INIT:Mount_START
      3216.090999 : INIT:Mount_END
      3323.061922 : post-fs-data: on modem start
      4556.043307 : BOOT_Animation:START
      6347.219691 : Zygote:Preload Start
      6374.771768 : Zygote:Preload Start
      7895.612845 : Zygote:Preload 3005 classes in 1139ms
      7900.031538 : Zygote:Preload 3005 classes in 1143ms
      8537.270153 : Zygote:Preload 343 obtain resources in 583ms
      8549.980691 : Zygote:Preload 343 obtain resources in 591ms
      8551.024768 : Zygote:Preload 41 resources in 13ms
      8562.582691 : Zygote:Preload 41 resources in 12ms
      8711.011691 : Zygote:Preload End
      8741.507384 : Zygote:Preload End
      9493.004153 : Android:PackageManagerService_Start
      9627.343230 : Android:PMS_scan_START
      9850.050538 : Android:PMS_scan_data_done:/system/framework
     12855.655461 : Android:PMS_scan_data_done:/system/priv-app
     14400.276230 : Android:PMS_scan_data_done:/system/app
     21861.967923 : Android:PMS_scan_data_done:/system/vendor/operator/app
     21913.608846 : Android:PMS_scan_data_done:/system/plugin
     21916.325384 : Android:PMS_scan_data_done:/data/app
     22236.198615 : Android:PMS_scan_END
     22308.189538 : Android:PMS_READY
     29178.269923 : BOOT_Animation:END
----------------------------------------

在串口log中搜索“Kernel_init_done”关键字,若有,则证明kernel已经启动ok,android已经启动,说明开机卡在android,
这个时候我们就需要看一下离线log,即mktlog(adblog),

若是么有搜到此关键字,说明卡在kernel阶段,我们可以找到对应版本的vmlinux,以及kernel节点PC指针位置,通过工具来看
程序走到哪个文件的哪一行出现了问题,举例如下:
[    1.680450]<2>-(2)[1:swapper/0]not find in scatter file error!
[    1.681172]<2>-(2)[1:swapper/0]ipanic_data_to_sd: dump PROC_CUR_TSK failed[-1]
[    1.682080]<2>-(2)[1:swapper/0]CPU: 2 PID: 1 Comm: swapper/0 Tainted: G        W    3.10.65 #1
[    1.683152]<2>-(2)[1:swapper/0]task: dbc31000 ti: dbc38000 task.ti: dbc38000
[    1.684031]<2>-(2)[1:swapper/0]PC is at DAL_SetScreenColor+0x74/0x9c
[    1.684822]<2>-(2)[1:swapper/0]LR is at DISP_GetScreenHeight+0x10/0x14
[    1.685639]<2>-(2)[1:swapper/0]pc : []    lr : []    psr: 80000113
[    1.685639]<2>sp : dbc39d38  ip : dbc39d10  fp : dbc39d54
[    1.687298]<2>-(2)[1:swapper/0]r10: c0c4b24c  r9 : dbdaae10  r8 : 7fa40000
[    1.688156]<2>-(2)[1:swapper/0]r7 : 00000000  r6 : 0000f800  r5 : dbe05280  r4 : e1580000
[    1.689176]<2>-(2)[1:swapper/0]r3 : 00030401  r2 : 000324a0  r1 : f800f800  r0 : 000c9280
[    1.690197]<2>-(2)[1:swapper/0]Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[    1.691311]<2>-(2)[1:swapper/0]Control: 10c0383d  Table: 4000406a  DAC: 00000015
[    1.692232]<2>-(2)[1:swapper/0]
......................
[    1.812743]<2>-(2)[1:swapper/0][] (DAL_Init+0x0/0xb8) from [] (mtkfb_probe+0x220/0x2e8)
[    1.813950] r6:db59d800 r5:e14bf000 r4:db59da70
[    1.814537]<2>-(2)[1:swapper/0][] (mtkfb_probe+0x0/0x2e8) from [] (driver_probe_device+0xc8/0x474)
[    1.815864] r8:c0d16708 r7:c0dba6e0 r6:c0dba6d4 r5:c0cba4b8 r4:c0d2a400
[    1.816709]<2>-(2)[1:swapper/0][] (driver_probe_device+0x0/0x474) from [] (__driver_attach+0x94/0x98)
[    1.818087]<2>-(2)[1:swapper/0][] (__driver_attach+0x0/0x98) from [] (bus_for_each_dev+0x68/0x9c)
[    1.819402] r6:c02f3b28 r5:c0cba4b8 r4:00000000 r3:00000000
[    1.820116]<2>-(2)[1:swapper/0][] (bus_for_each_dev+0x0/0x9c) from [] (driver_attach+0x24/0x28)
[    1.821409] r6:c0cacf88 r5:c0cba4b8 r4:db5f8c80
[    1.821993]<2>-(2)[1:swapper/0][] (driver_attach+0x0/0x28) from [] (bus_add_driver+0x1d0/0x274)
[    1.823307]<2>-(2)[1:swapper/0][] (bus_add_driver+0x0/0x274) from [] (driver_register+0x80/0x148)
[    1.824622] r7:dbc38030 r6:00000000 r5:c0d29000 r4:c0cba4b8
[    1.825340]<2>-(2)[1:swapper/0][] (driver_register+0x0/0x148) from [] (platform_driver_register+0x58/0x60)
[    1.826753] r8:c0c20908 r7:dbc38030 r6:00000000 r5:c0d29000 r4:00000006
r3:00000000
[    1.827743]<2>-(2)[1:swapper/0][] (platform_driver_register+0x0/0x60) from [] (mtkfb_init+0x14/0x70)
[    1.829111]<2>-(2)[1:swapper/0][] (mtkfb_init+0x0/0x70) from [] (do_one_initcall+0x11c/0x230)
[    1.830384] r4:00000006 r3:00000000
[    1.830835]<2>-(2)[1:swapper/0][] (do_one_initcall+0x0/0x230) from [] (kernel_init_freeable+0x144/0x1ec)
[    1.832246]<2>-(2)[1:swapper/0][] (kernel_init_freeable+0x0/0x1ec) from [] (kernel_init+0x10/0x170)
[    1.833603]<2>-(2)[1:swapper/0][] (kernel_init+0x0/0x170) from [] (ret_from_fork+0x14/0x3c)
[    1.834854] r5:c08f4cbc r4:00000000
[    1.835295]<2>-(2)[1:swapper/0]Code: 11861806 13a03000 0a000003 e2833001 (e4841004)
[    1.836259]<2>-(2)[1:swapper/0]---[ end trace da227214a82491bb ]---
[    1.837038]<2>-(2)[1:swapper/0]Kernel panic - not syncing: Fatal exception

开机时发生kernel panic,PC指针指向DAL_SetScreenColor+0x74/0x9c位置pc : [] ,通过vmlinux来解析出具体代码位置我们就知道为啥出问题了

4. 卡在开机动画时我们就得需要mtklog即离线log(mtk平台),也可以通过adb log来抓取
指令:
adb logcat -v time
adb logcat -v time|grep "***"

5.附上参考文档一篇

分类: Android平台

[DESCRIPTION]
在发生各种异常时,通常从log看到的是各种地址和数据,这些信息基本无法阅读,分析也很困难。
我们需要将这种人类无法阅读的信息转换成容易理解的信息。比如将函数地址转换成所在的文件和行号。
在log里恰恰含有大量这种地址信息。因此转换为所在文件和行号有助于我们分析问题。
 
[SOLUTION]
这个转换需要借助一个GNU工具:arm-linux-androideabi- addr2line(ARM 32位版本)或aarch64-linux-android-addr2line(ARM 64位版本)
工具位置(具体以实际目录位置为准):
ARM 32位版本:prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm- linux-androideabi-addr2line
ARM 64位版本:prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin /aarch64-linux-android-addr2line
使用方法:
arm-linux-androideabi-addr2line -Cfe $symbol_file 0xyyyyyyyy
其中的0xyyyyyyyy是从log提取的地址。$symbol_file为地址所在的符号文件,该文件包含调试信 息。
 
该工具需要搭配对应的符号文件才行,那这个符号文件是什么呢?这要看你要查询的地址是属于哪个符号文件的了。
举例:log里的地址是lk的,那lk对应的符号文件是:out/target/product/$proj/obj /bootloader_obj/build-$proj/lk
如果是kernel的,对应的符号文件是:out/target/product/$proj/obj /kernel_obj/vmlinux(老版本的位置在kernel/out/vmlinux)
如果是preloader的,对应的符号文件是:out/target/product/$proj/obj /preloader_obj/bin/preloader_$proj.elf
 
实例1:
有一次在lk里发生了重启,抓取uart log如下:
kedump add: SYS_MINI_RDUMP[0] 1000/1000@a00
[1460] data abort, halting
[1460] r0 0x41e49ec8 r1 0x41e31b03 r2 0x41e49ed7 r3 0x00000000
[1460] r4 0x43ff0000 r5 0x43ff0bae r6 0x41e31b04 r7 0x43ff0bd6
[1460] r8 0x41e31ad4 r9 0x00000014 r10 0x00001a00 r11 0x00000000
[1460] r12 0x00000061 usp 0x00000000 ulr 0x00000000 pc 0x41e1b918
[1460] spsr 0x00000173
/* 之后就重启了 */
我们需要知道在什么地方发生异常了,PC是当时发生异常的地址。拿到对应的lk,用如下命令转换:
arm-linux-androideabi-addr2line -Cfe lk 0x41e1b918
kedump_to_expdb
bootable/bootloader/lk/app/mt_boot/aee_KEDump.c:219
很明显就可以看到是aee_KEDump.c的219行出问题了,赶紧查看代码分析吧。
 
实例2:
在kernel发生了panic,抓取kernel log(db里的SYS_KENREL_LOG)如下:
[17600.585313]<1>-(1)[1602:wpa_supplicant]PC is at sock_rfree+0x20/0x38
[17600.585327]<1>-(1)[1602:wpa_supplicant]LR is at netlink_skb_destructor+0x14/0x1c
......
[17600.590428]<1>-(1)[1602:wpa_supplicant]Call trace:
[17600.590442]<1>-(1)[1602:wpa_supplicant][] sock_rfree+0x20/0x38
[17600.590458]<1>-(1)[1602:wpa_supplicant][] skb_release_head_state+0x5c/0xe4
异常发生在sock_rfree()函数里,但是不知道哪一行异常了,异常的地址是 ffffffc000832784,拿到对应的vmlinux,转换:
aarch64-linux-android-addr2line -Cfe vmlinux 0xffffffc000832784
sk_mem_uncharge
kernel-3.10/include/net/sock.h:1415
问题在sock.h的1415行异常,需要进一步分析。
 
注意:
  • 这个符号文件必 须是和烧录的image一起生成的,如果被重新编译过生成的,那么log里的地址和符号文件可能对应的不上,工具可能输出错 误的结果。
  • 如果不确定符号 文件是32位还是64位,则直接使用64位版本。


阅读(3198) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~