Welcome 微信登录

首页 / 操作系统 / Linux / Dalvik在x86下的编译及调试

Android Source中默认的Dalvik编译目标是ARM平台,只能在模拟机或者真机上运行,不过如果想研究它我觉得还是在x86下方便点.1、如果使用Ubunut的话,把gcc版本换成4.3的。gcc -v可以查看当前版本。sudo apt-get install gcc-4.3 g++-4.3sudo ln -s /usr/bin/gcc-4.3 /usr/bin/gccsudo ln -s /usr/bin/g++-4.3 /usr/bin/g++默认的4.4 compile时要求更严格,会出现error: invalid conversion from‘const char*’ to ‘char*’的提示。 2、在源代码跟目录下,运行:. build/envsetup.shlunch 2这主要设置编译的目标平台。 注:默认的平台信息如下:PLATFORM_VERSION_CODENAME=AOSPPLATFORM_VERSION=AOSPTARGET_PRODUCT=genericTARGET_BUILD_VARIANT=engTARGET_SIMULATOR=TARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=armHOST_ARCH=x86HOST_OS=linuxHOST_BUILD_TYPE=releaseBUILD_ID=OPENMASTER 选用上述平台后的信息如下:PLATFORM_VERSION_CODENAME=AOSPPLATFORM_VERSION=AOSPTARGET_PRODUCT=simTARGET_BUILD_VARIANT=engTARGET_SIMULATOR=trueTARGET_BUILD_TYPE=debugTARGET_BUILD_APPS=TARGET_ARCH=x86HOST_ARCH=x86HOST_OS=linuxHOST_BUILD_TYPE=releaseBUILD_ID=OPENMASTER 具体需要什么平台可以根据envsetup.sh文件内容进行选择。我这边是x86.  3、编译相对应的模块:make dalvikvm core ext dexopt framework android.policy services dalvikvm后面的几个模块是VM本身需要的一些library,比如ext.jar。如果make所有模块也可以,不过耗时就长多了,而且出现编译错误的可能性就大多了。如果只是为了研究dalvik的移植或者调试,上述模块基本够了。需要注意的是,在我参考的一篇文章中没有dexopt项,在运行时会出现该错误“E/dalvikvm(1540):execv "mnt/hd/Android/out/debug/host/linux-x86/pr/sim/system/bin/dexopt" failed: No such file or directory”,dexopt是对dex文件进行优化的一个模块,一定需要生成。 生成的文件在源码目录下的out文件夹内。可用find  .  -name  dalvikvm查找dalvikvm文件 4、测试hello程序:hello.java代码: public class hello{      public static void main(String args[])       {                  System.out.println("hello world");      }}  注意:我是将hello.java和makefile文件放在了Android源码的根目录下,且我的源码是挂载在第二硬盘的下/mnt/hd/Android,因此得到:ANDROID_SRC_DIR := /mnt/hd/Android,只需对文件目录相应改变即可。又因为Android目录下已有一个Makefile,因此避免冲突将hello程序的makefile命名为HelloMakefile。 HelloMakefile:ANDROID_SRC_DIR := /mnt/hd/Androidandroid_dir_dx = $(ANDROID_SRC_DIR)/out/host/linux-x86/bin/dxall:      javac hello.java      $(android_dir_dx) --dex --output=hello.jar hello.classclean:      @rm *.jar *.class 完成上述步骤后,会生成hello.jar、hello.classAndroid目录下所有文件如下图所示:
5、如果直接运行/mnt/hd/Android/out/debug/host/linux-x86/pr/sim/system/bin/dalvikvm -cp hello.jar hello则会出现以下错误:E/dalvikvm( 4668): ERROR: must specify non-"." bootclasspathW/dalvikvm( 4668): JNI_CreateJavaVM failedDalvik VM init failed (check log file) 原因是虚拟机运行的一些相关文件没有加载。因此需要一个脚本文件,命名为rund.sh: #!/bin/sh base=`pwd` # configure root dir of interesting stuffroot=$base/out/debug/host/linux-x86/pr/sim/systemexport ANDROID_ROOT=$root # configure bootclasspathbootpath=$root/frameworkexport BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar # this is where we create the dalvik-cache directory; make sure it existsexport ANDROID_DATA=/tmp/dalvik_$USERmkdir -p $ANDROID_DATA/dalvik-cache exec gdb $root/bin/dalvikvm 而后输入以下命令即可运行gdb程序,调试dalvik的运行了:./rund.sh然后在gdb调试下输入运行参数:set  args  -cp  hello.jar  hello设置断点b  main以下就可以单步调试dalvik了。以下是我的运行结果: zhutou@zhutou-desktop:/mnt/hd/Android$ ./rund.sh GNU gdb (GDB) 7.1-UbuntuCopyright (C) 2010 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.  Type "show copying"and "show warranty" for details.This GDB was configured as "i486-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /mnt/hd/Android/out/debug/host/linux-x86/pr/sim/system/bin/dalvikvm...done.(gdb) set args -cp hello.jar hello(gdb) b mainBreakpoint 1 at 0x8048822: file dalvik/dalvikvm/Main.c, line 142.(gdb) rStarting program: /mnt/hd/Android/out/debug/host/linux-x86/pr/sim/system/bin/dalvikvm -cp hello.jar hello[Thread debugging using libthread_db enabled] Breakpoint 1, main (argc=4, argv=0xbfffebd4) at dalvik/dalvikvm/Main.c:142142     {(gdb) cContinuing.[New Thread 0x1439b70 (LWP 4698)][New Thread 0x1c3ab70 (LWP 4699)]Hello World! [Thread 0x1439b70 (LWP 4698) exited][Thread 0x1c3ab70 (LWP 4699) exited] Program exited normally.