Android基本debug手法 1. KK/build/envsetup.sh a) lunch b) croot c) cgrep: Greps on all local C/C++ files. d) jgrep: Greps on all local Java files e) resgrep: Greps on all localres/*.xml files 2. init.tvserver.sh a) if [ ! -e/system/rtk_rootfs/usr/local/etc/dvdplayer/noaplogprint ]; then cd /system/rtk_rootfs/usr/local/bin;./RootApp TvServer > /dev/c**ole 2>&1 & else cd /system/rtk_rootfs/usr/local/bin;./RootApp TvServer > /dev/c**ole 1>/dev/null & fi à cd /system/rtk_rootfs/usr/local/bin; logwrapper ./RootApp TvServer& b) 有需要开机执行的命令或脚本可以加在这个shell里面 Eg: factory load 3. exec background logcat logcat –v time> /scard/logcat.txt & 4. /data/system/packages.xml a) packages.xml里面记录了系统当中安装的APK的所有属性,权限等信息。当系统中的APK安装、删除、升级时,文件就会被更新 root@android:/data/system# cat packages.xml | grep homeshell < package name="com.yunos.tv.homeshell" codePath="/system/app/AliTvHomeshell.apk"nativeLibraryPath="/data/app-lib/AliTvHomeshell" flags="572997" ft="15419d30f18" it="15419d30f18" ut="15419d30f18" version="2101090103" userId="10030" > b) dumpsys package 包名 | grepversion root@android:/ # dumpsys package com.yunos.tv.homeshell | grepversion versionCode=2101090103targetSdk=22 versionName=DVB_TV_HOME_HKC_Metro_1.9.1.03_R 5. 关闭/打开DirectVO a) 关闭DVO setprop media.sf.enable_vo 0 setprop media.sf.enable_vo_zero_copy 0 b) 打开DVO setprop media.sf.enable_vo 1 setprop media.sf.enable_vo_zero_copy 1 6. dumpsys SurfaceFlinger a) 当遇到画面显示比例异常或者画面卡住时,异常状态下输入cmd “dumpsys SurfaceFlinger ” + Layer 0xb88b8140(SurfaceView) Region transparentRegion (this=0xb88b82c8,count=1) [ 0, 0, 0, 0] Region visibleRegion (this=0xb88b8148,count=1) [ 0, 88, 1280, 631] layerStack= 0, z= 21015, pos=(0,88), size=(1280, 543), crop=( 0, 0,1280, 543), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000000,tr=[1.00, 0.00][0.00, 1.00] client=0xb88b50e8 format= 4, activeBuffer=[1024x576:1280,32315659], queued-frames=0, mRefreshPending=0 mTexName=55586330 mCurrentTexture=0 mCurrentCrop=[0,0,1024,576]mCurrentTransform=0 mAbandoned=0 -BufferQueuemMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0,default-size=[1280x543], default-format=4, transform-hint=00, FIFO(0)={} >[00:0xb88a2e18] state=ACQUIRED,0xb88beb80 [1024x 576:1280,32315659] [01:0xb88be4e0] state=DEQUEUED,0xb88bcf80 [1024x 576:1280,32315659] [02:0xb88b7758] state=DEQUEUED,0xb88a30f8 [1024x 576:1280,32315659] ACQUIRED: 这个是目前在show的画面 DEQUEUED: 这个是producerhold住的buffer,准备用来写如decode之后的data QUEUED:这个是一张ready的画面,可以由c**umer拿去show 如果可以正常往下走的话,应该是 quequed的那一张变成acquired, acquired的那一张变成free, dequeued那一张由omx写进decode之后的data后变成queued. b) 遇到画面显示比例异常时还可以使用Eclipse DDMS中的”dump View Hierarchy for UI Automator”工具 7. Open video fw/audio fw/kernellog a) Open video f/w log touch /data/realtek/ videodebug b) Open audio f/w log touch /data/realtek/ audiodebug c) Open kernel log touch /data/realtek/kerneldebug d) How to adjust kernel logpriority echo 8 > /proc/sys/kernel/printk 8. Lowmemorykiller low memory killer就是在系统内存低于某值时,清除相关的程序,保障系统保持拥有一定数量的空闲内存 Lowmemorykiller根据三个参数来决定哪个进程需要被kill掉 : oom_adj/minfree/cache memory a) 130|root@android:/ # cat/etc/lowmemorykiller.txt adj:0,1,2,3,9,15 #need divfor each element minfree:1536,2048,4096,8192,11520,19200 130|root@android:/# cat /sys/module/lowmemorykiller/parameters/adj 0,58,117,176,529,1000 130|root@android:/# cat /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,8192,11520,19200 PS: minfree以page为单位,所以实际大小要乘以4 b) 进程优先级 ( oom_adj ) /kernel/android/KK/frameworks/base/services/java/com/android/server/am/ProcessList.java // This is a process only hosting activities that are not visible, // so it can be killed without any disruption. staticfinal int CACHED_APP_MAX_ADJ = 15; static final int CACHED_APP_MIN_ADJ = 9; // Thisis a process holding an application service -- killing it will not // have much of an impact as far as theuser is concerned. static final int SERVICE_ADJ = 5; // This is a process with a heavy-weightapplication. It is in the // background, but we want to try to avoidkilling it. Value set in // system/rootdir/init.rc on startup. static final int HEAVY_WEIGHT_APP_ADJ = 4; // This is a process currently hosting abackup operation. Killing it // is not entirely fatal but is generally abad idea. static final int BACKUP_APP_ADJ = 3; // This is a process only hosting componentsthat are perceptible to the // user, and we really want to avoidkilling them, but they are not // immediately visible. An example isbackground music playback. static final int PERCEPTIBLE_APP_ADJ = 2; // This is a process only hostingactivities that are visible to the // user, so we'd prefer they don'tdisappear. static final int VISIBLE_APP_ADJ = 1; // This is the process running the currentforeground app. We'd really // rather not kill it! static final int FOREGROUND_APP_ADJ = 0; // This is a systempersistent process, such as telephony. Definitely // don't want to kill it,but doing so is not completely fatal. static final int PERSISTENT_PROC_ADJ = -12; c) kernel/linux/linux-3.7.2/drivers/staging/android/lowmemorykiller.c lowmem_shrink() –> 找到符合条件的process并将其kill掉 当cache memory size < = minfree * 4时,lmk会将minfree对应的oom_adj或大于此oom_adj的进程kill掉,具体规则见lowmem_shrink函数 Ps: cache memory size可以通过“cat /proc/meminfo”查看 static int lowmem_shrink(structshrinker *s, struct shrink_control *sc) { … for_each_process(tsk){ struct task_struct *p; int oom_score_adj; if (tsk->flags & PF_KTHREAD) continue; p = find_lock_task_mm(tsk); if (!p) continue; if (test_tsk_thread_flag(p,TIF_MEMDIE) && time_before_eq(jiffies, lowmem_deathpending_timeout)) { task_unlock(p); rcu_read_unlock(); lowmem_print(4, "lowmem_shrink %lu,%x, wait %s %d %d %d (%s %d)\n", sc->nr_to_scan,sc->gfp_mask, p->comm, p->pid,jiffies, lowmem_deathpending_timeout,current->comm, current->pid); return 0; } oom_score_adj =p->signal->oom_score_adj; if (oom_score_adj <min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; if (selected) { if (oom_score_adj <selected_oom_score_adj) continue; if (oom_score_adj ==selected_oom_score_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_score_adj =oom_score_adj; lowmem_print(2, "select %d(%s), adj %d, size %d, to kill (%s %d) %d\n", p->pid, p->comm,oom_score_adj, tasksize, current->comm, current->pid, jiffies); } … } #define OOM_SCORE_ADJ_MAX 1000 #define OOM_DISABLE(-17) static intlowmem_oom_adj_to_oom_score_adj(int oom_adj) { if (oom_adj == OOM_ADJUST_MAX) returnOOM_SCORE_ADJ_MAX; else return (oom_adj *OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; } d) 若发现apk自动退出且从log中看不出异常信息,可能是该apk进程被lmk干掉了 确认方法: 开启kernel log,并将kernel log priority 设为8,重启平台后复现 Kernellog: <6>[ 729.920769] lowmemorykiller: Killing'way.tvlive2:cde' (1579), adj 58, <6>[ 729.920769] to free 65628kB on behalf of 'kswapd0' (30) because <6>[ 729.920769] cache 8156kB is below limit 8192kB for oom_score_adj 58 <6>[ 729.920769] Free memory is3992kB above reserved 9. 系统卡死 a) ANR (ApplicationNot Responding) 默认情况下,在android中Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒。超出就会提示应用程序无响应(ANR:ApplicationNot Responding)对话框 anr时会在板子/data/anr目录下产生文档”traces.txt”,其中详细描述了卡住的位置 Ps:新产生的traces.txt会把旧的覆盖掉,所以出现问题时要尽早将traces.txt拉出来 b) CPU满负载 这种情况一般无traces.txt产生,且串口输入命令响应缓慢 i. top –t –m 5 User 0%, System 99%, IOW 0%, IRQ 0% User 41 + Nice 1 + Sys 10831 + Idle0 + IOW 0 + IRQ 0 + SIRQ 58 = 10931 PID TID PR CPU%S VSS RSS PCYUID Thread Proc
3018 3058 0 61% R 444140K 50912K fgu0_a38 way.tvlive2:cde com.elinkway.tvlive2:cde 51 51 0 12% D 0K 0K fg root mmcqd/0 92 3255 0 1% S 73996K 9628K fg media NuPlayerDecoder /system/bin/mediaserver 31 31 0 1% S 0K 0K fg root ksmd 4 4 0 0% S 0K 0K fg root ksoftirqd/0 ii. vmstat procs memory system cpu r b free mapped anon slab in cs flt us ni sy id wa ir 2 24 29184 1400 171956 21588 719121188 1576 1 0 99 0 0 0 2 30 29476 1316 171872 21588 1068631240 2581 0 0 99 0 0 0 2 29 29804 1148 171932 21588 435213105 604 0 0 99 0 0 0 2 19 29672 1288 171848 21588 674720415 1657 0 0 99 0 0 0 2 25 29672 1312 171924 21588 396211264 668 2 0 99 0 0 0 cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目。每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的 iii. systrace c) 死锁 遥控无响应,无traces.txt产生,通过debuggerd –b 命令将怀疑进程的所有backtrace印出来,并逐个线程查询是否有线程间死锁问题 root@android:/ # ps - T USER PID PPID VSIZE RSS WCHAN PC NAME root 1950 1915 105632 5372 ffffffff b6635918 STvServer root@android:/ # debuggerd -b 1950 >/data/TvServer_debuggerd.txt stack工具可以自动做addr2line动作,目前只适用于TvServer: python stack --kk-home=~/Disk2/2984_KKTV/kernel/android/KK--symbols-dir=TvServer TvServer_debuggerd.txt > TvServer_debuggerd_stack.txt PS: TvServer必须是not stripped版本才可以转译,确认方法如下: [malone_ma@AE5 TvServer]$ file TvServer TvServer: ELF 32-bit LSB shared object, ARM, version 1(SYSV), dynamically linked (uses shared libs), not stripped 10. Crash (/data/tombstones) 空指针调用/除0错误等会造成crash,而一般情况下apkcrash只会导致应用退出,大部分导致系统重启的是TvServer crash 出现crash时系统会在/data/tombstones文件夹下产生tombstone_xx文档 JB/kernel/android/KK/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-addr2line -C -f -e TvServer 000dd221 11. 快速替换video fw的方法 a) 将video_firmware.bin拷贝至u盘根目录 b) 按空格键AC上电 c) usb start d) fatload usb 0:1 0x01a00000video_firmware.bin e) go all PS:重启后新video fw失效
|