Android 调试tips 记录

来源:互联网 发布:soap和json 编辑:程序博客网 时间:2024/06/14 05:42

开一个贴收集一些TIPs 记录, 后面工作中可能会用到:

 

一. android  input 设备debug技巧:

 

1、驱动层

        检查是否有点上报

        adb shell getevent -l /dev/input/eventX



          ( getevent 出来的为scan code , 需要通过kl 来转换为按键码标签,

按键的scan code 为0073(16进制), 则对应的标签KEY_VOLUMEUP

TP的scan code看第三列, 为x,y 坐标)



        检查input设备支持的属性值

        adb shell getevent -i /dev/input/eventX


2、Native层

        检查驱动上报的点是否被InputReader转发给上层

        在TouchInputMapper::sync(nsecs_t when)函数中,打印相关的变量值,检查报点路径是否正常。驱动已经报点,但是上层收不到点的情况大致有以下几种:

        a. 设备模式被设为禁用模式,mDeviceMode == DEVICE_MODE_DISABLED

  引起此问题的原因是,在注册input device时,有些属性值设置不合法,导致在configure阶段,走了异常流程;

        b. 设备类型不正确,走了其他路径


3、Java层

        在ViewRootImpl.java文件的onInputEvent( )函数中添加打印信息,检查底层上报的点,是否通过Framework层成功上报了。

        一般来讲,如果onInputEvent能收到点,报点基本上是OK的。

       有些特殊情况除外,报点的消息类型不正确或者TP的横竖坐标搞反了,会出现上层收点了,但是TP仍然无法正常使用。


 

二. Android kernel Crash后,定位出错点的方法(GDB)

 

 

1. 将/prebuild/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-gdb 拷贝到/usr/local/bin下


2. 进入out/target/product/工程名xxx/obj/KERNEL_OBJ 目录,找到文件vmlinux


3. 执行arm-linux-androideabi-gdb vmlinux,进入gdb调试界面


4. 输入 list  *  函数名+行号,会显示出错对应的文件和行号

 

 

三.  Android各代码层获取系统时间的方法

 

1. 在java层,long now = SystemClock.uptimeMillis();


2. 在native层,nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);


3. 在驱动层,s64 time = ktime_to_us(ktime_get());

 唯一的不足是转换得到的是UTC时间,同北京时间差8小时。要想达到用户态localtime()的效果,必须获得/etc/localtime 中的时区信息

#include <linux/timer.h>
#include <linux/timex.h>
#include <linux/rtc.h>

/*添加到合适位置*/

struct timex  txc;
struct rtc_time tm;
do_gettimeofday(&(txc.time));
rtc_time_to_tm(txc.time.tv_sec,&tm);
printk(“UTC time :%d-%d-%d %d:%d:%d /n”,tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);

 

四.  Linux测量kernel子模块加载时间的方法

 

1. 在文件kernel/init/main.c里面,在接口do_one_initcall( )中,将initcall_debug设置为true,然后编译boot.img


2. 使用adb shell cat /proc/kmsg | grep initcall 来查看模块加载时间

 

 

五.  Android怎样使用系统属性

 

1. 在system.prop里面添加需要使用的系统属性,添加完后需要编译生成system.img


2. 在native层,使用property_set(...)和property_get(...)来存取系统属性


3. 在java层, 使用SystemProperties.set(...)和SystemProperties.get(...)来存取系统属性


4. 在adb shell命令行,使用getprop和setprop来存取系统属性




六.  建立Sysfs  调试开关

    在调试驱动过程中,打印log必不可少。有时候需要这样:不想系统一直有串口输出(因为可能影响性能),但又想在某个时刻去打开我们想要的打印。

   可以这样做,建立一个sysfs接口,并在代码用一个全局变量控制调试语句的打印,然后通过写接口值改变这个全局变量即可.




七.  android 使用memory 分析


系统中应用 -> native


http://elinux.org/Android_Memory_Usage



八.    adb   shell 启动应用程序


am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity



九.    android 权限管理


Android 权限管理
控制连入的user(console)是否是root权限,由adbd来控制,代码在/system/core/adb/adb.c
所有的权限在头文件
/home/luq/Android/mydroid/system/core/include/private/android_filesystem_config.h

然后就是利用su命令来做需要改变各种权限的事情了。其实就是uid和文件权限的一些关系罢了!(由kernel中的kernel_start启动UID为0的init,来初始化一些事情)Cymod中就是利用ROM Manager和superuser来配合完成的。同时,Cymod更改了/system/extras/su/中的su的实现,方便对于root权限的控制.

   由应用程序superuser维护了一个系统中所有应用程序权限的db,当有应用程序尝试调用su这个命令时,会使用上述修改后的su,从而调用system/extra/su/activity.cpp中的send_intent函数发送一个定制的broadcast(这里很关键,可以从中看到如何从native层构建一个有效的intent给java的activity manager来解析), 这个broadcast会被superuser接收到,并根据传递上来的uid,gid等信息查询


关于Android的权限控制,参看浅析android中的权限管理--用户安装的apk的uid,gid是如何分配的



十.   busybox for  android 使用


http://benno.id.au/blog/2007/11/14/android-busybox



十一.     apk 签名


关于Android中的签名
关于签名:
build/target/product/security目录中有四组默认签名供Android.mk在编译APK使用:
1、testkey:普通APK,默认情况下使用。
2、platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
3、shared:该APK需要和home/contacts进程共享数据。
4、media:该APK是media/download系统中的一环。
应用程序的Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪个key签名,未指定的默认用testkey.





 

原创粉丝点击