| 
 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失效  
 |