转载自:http://blog.csdn.net/yumufenglin/article/details/6190967

此文比较早,仅供参考。最新的文章,请看我的:

http://memory.blog.51cto.com/6054201/1215232

写这个的时候借鉴了许多网上文章,不一一列举,对此表示感谢!

Android Source中默认的Dalvik编译目标是ARM平台,只能在模拟机或者真机上运行,不过如果想研究它我觉得还是在x86下方便点.

1、如果使用Ubunut的话,把gcc版本换成4.3的。

gcc -v可以查看当前版本。

sudo apt-get install gcc-4.3 g++-4.3

sudo ln -s /usr/bin/gcc-4.3 /usr/bin/gcc

sudo ln -s /usr/bin/g++-4.3 /usr/bin/g++

默认的4.4 compile时要求更严格,会出现error: invalid conversion from

‘const char*’ to ‘char*’的提示。

2、在源代码跟目录下,运行:

. build/envsetup.sh

lunch 2

这主要设置编译的目标平台。

注:

默认的平台信息如下:

PLATFORM_VERSION_CODENAME=AOSP

PLATFORM_VERSION=AOSP

TARGET_PRODUCT=generic

TARGET_BUILD_VARIANT=eng

TARGET_SIMULATOR=

TARGET_BUILD_TYPE=release

TARGET_BUILD_APPS=

TARGET_ARCH=arm

HOST_ARCH=x86

HOST_OS=linux

HOST_BUILD_TYPE=release

BUILD_ID=OPENMASTER

选用上述平台后的信息如下:

PLATFORM_VERSION_CODENAME=AOSP

PLATFORM_VERSION=AOSP

TARGET_PRODUCT=sim

TARGET_BUILD_VARIANT=eng

TARGET_SIMULATOR=true

TARGET_BUILD_TYPE=debug

TARGET_BUILD_APPS=

TARGET_ARCH=x86

HOST_ARCH=x86

HOST_OS=linux

HOST_BUILD_TYPE=release

BUILD_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.-namedalvikvm查找dalvikvm文件

4、测试hello程序:

hello.java代码:

public class hello{

public static void main(String args[])

{

System.out.println("hello world");

}

}

注意:我是将hello.javamakefile文件放在了Android源码的根目录下,且我的源码是挂载在第二硬盘的下/mnt/hd/Android,因此得

到:ANDROID_SRC_DIR := /mnt/hd/Android,只需对文件目录相应改变即可。又因为Android目录下已有一个Makefile,因此避免冲突

hello程序的makefile命名为HelloMakefile

HelloMakefile:

ANDROID_SRC_DIR := /mnt/hd/Android

android_dir_dx = $(ANDROID_SRC_DIR)/out/host/linux-x86/bin/dx

all:

javac hello.java

$(android_dir_dx) --dex --output=hello.jar hello.class

clean:

@rm *.jar *.class

完成上述步骤后,会生成hello.jarhello.class

Android目录下所有文件如下图所示:

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-'.' bootclasspath

W/dalvikvm( 4668): JNI_CreateJavaVM failed

Dalvik VM init failed (check log file)

原因是虚拟机运行的一些相关文件没有加载。因此需要一个脚本文件,命名为

rund.sh

#!/bin/sh

base=`pwd`

# configure root dir of interesting stuff

root=$base/out/debug/host/linux-x86/pr/sim/system

export ANDROID_ROOT=$root

# configure bootclasspath

bootpath=$root/framework

export 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 exists

export ANDROID_DATA=/tmp/dalvik_$USER

mkdir -p $ANDROID_DATA/dalvik-cache

exec gdb $root/bin/dalvikvm

而后输入以下命令即可运行gdb程序,调试dalvik的运行了:

./rund.sh

然后在gdb调试下输入运行参数:

setargs-cphello.jarhello

设置断点

bmain

以下就可以单步调试dalvik了。

以下是我的运行结果:

zhutou@zhutou-desktop:/mnt/hd/Android$ ./rund.sh

GNU gdb (GDB) 7.1-ubuntu

Copyright (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 main

Breakpoint 1 at 0x8048822: file dalvik/dalvikvm/Main.c, line 142.

(gdb) r

Starting 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:142

142{

(gdb) c

Continuing.

[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.