月度归档:2011年09月

android chromium要来了?

之前做android浏览器的时候,还考虑过将chromium移植到android。不过浏览了一下chromium的源码后就放弃了,chromium代码库太庞大了,不是几个人能搞定的。这两天网上满天飞的消息,google开始着手将chrome移植到android上了。不过究其消息来源,并非google官方声明,而是google开发团队的一位大牛Andrei Popescu在webkit的mail list写了下面的话:

We plan to start by setting up a webkit.org build bot that will compile Chromium’s DRT for Android using the Android NDK, SDK and toolchain. We anticipate a reasonably small set of changes to the Chromium port to achieve this. We’re fully committed to maintaining this new flavor of the Chromium port of WebKit and having a build bot up and running as soon as possible will make this an easier task. At the same time, we will be removing the existing incomplete Android port. This includes the Android-specific code in WebCore/platform/android, as well as any code guarded by the PLATFORM(ANDROID) macro.

简单说,就是Google的Android团队要对于Android里的浏览器进行改造,将这个开源的移动浏览器跟另外一个同样开源的桌面浏览器进行整合,移除Android浏览器独有的特殊代码,取而代之Chromium的代码。

以google的实力,决定将chromium移到android上,肯定是办得到的。现在的问题是,会在android的哪个版本中出现?毫无疑问,这个时候决定整合浏览器,一定是冲着android平板而来(对于智能手机,现有的android浏览器可以应付得了),况且移植工作量也不小,所以估计要在android 4.0之后才可以看得到。

我比较关心的是,如果android中有了chromium浏览器,我们做浏览器的是否会失业呢?

使用ndk-stack追踪程序崩溃

程序崩溃无疑是程序员最头疼的事情,而android native程序崩溃简直是令程序员崩溃。Android java程序在异常之前还打印出代码调用栈,让程序员有迹可寻,结合单步调试,定位问题相对容易些。而native程序崩溃,只会打印出一段天书,让人摸不着头脑。比如,下面就是一段native程序异常后,在logcat中打印出的信息:

09-01 07:20:39.170: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
09-01 07:20:39.170: INFO/DEBUG(31): Build fingerprint: ‘generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys’
09-01 07:20:39.180: INFO/DEBUG(31): pid: 339, tid: 347  >>> mogoweb.browser.app <<<
09-01 07:20:39.180: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr bbadbeef
09-01 07:20:39.180: INFO/DEBUG(31):  r0 00000093  r1 ffffff1c  r2 00000000  r3 bbadbeef
09-01 07:20:39.180: INFO/DEBUG(31):  r4 0029d378  r5 0029d2c0  r6 00000000  r7 43eaeeb4
09-01 07:20:39.180: INFO/DEBUG(31):  r8 43fcdb4c  r9 43eaeea8  10 43eaee90  fp 43fcda3c
09-01 07:20:39.180: INFO/DEBUG(31):  ip 00000029  sp 43fcda28  lr 822d6ee8  pc 822d6ef0  cpsr 00000010
09-01 07:20:39.270: INFO/ActivityManager(61): Displayed mogoweb.browser.app/.BrowserActivity: +1s98ms
09-01 07:20:39.669: INFO/DEBUG(31):          #00  pc 002d6ef0  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.669: INFO/DEBUG(31):          #01  lr 822d6ee8  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.669: INFO/DEBUG(31): code around pc:
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ed0 e08f3003 e1a02003 e59f3038 e08f3003
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ee0 eb2a28bf eb2a290b e59f302c e3a02000
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ef0 e5832000 e3a03000 e12fff33 e51b3008
09-01 07:20:39.669: INFO/DEBUG(31): 822d6f00 e1a00003 e24bd004 e8bd8800 0173faf0
09-01 07:20:39.669: INFO/DEBUG(31): 822d6f10 00cea68c 00cec48c 00cea6c0 bbadbeef
09-01 07:20:39.669: INFO/DEBUG(31): code around lr:
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ec8 e3a01040 e59f3040 e08f3003 e1a02003
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ed8 e59f3038 e08f3003 eb2a28bf eb2a290b
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ee8 e59f302c e3a02000 e5832000 e3a03000
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ef8 e12fff33 e51b3008 e1a00003 e24bd004
09-01 07:20:39.679: INFO/DEBUG(31): 822d6f08 e8bd8800 0173faf0 00cea68c 00cec48c
09-01 07:20:39.679: INFO/DEBUG(31): stack:
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9e8  83875a54  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9ec  82fc1554  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9f0  00000040 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9f4  82fc3364  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9f8  43fcda24 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9fc  82fc3364  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda00  00000040 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda04  82fc1554  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda08  43fcda24 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda0c  82d61244  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda10  82fc15a4  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda14  82fc3364  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda18  00000040 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda1c  82fc1554  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda20  df002777 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda24  e3a070ad 
09-01 07:20:39.690: INFO/DEBUG(31): #00 43fcda28  4051f020  /dev/ashmem/dalvik-heap (deleted)
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda2c  00000000 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda30  0029d2c0  [heap]
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda34  0029d378  [heap]
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda38  43fcdaac 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda3c  82330ec0  /data/data/mogoweb.browser.app/lib/libmogowebcore.so
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda40  43fcdac8 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda44  0029d2c0  [heap]
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda48  00000003 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda4c  0029d2c0  [heap]
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda50  c0000000 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda54  000000da 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda58  43fcdb4c 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda5c  43eaeea8 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda60  43eaee90 
09-01 07:20:39.699: INFO/DEBUG(31):     43fcda64  afd1413f  /system/lib/libc.so
09-01 07:20:39.699: INFO/DEBUG(31):     43fcda68  40098e88  /dev/ashmem/dalvik-heap (deleted)
09-01 07:20:39.699: INFO/DEBUG(31):     43fcda6c  800680e3  /system/lib/libdvm.so
09-01 07:20:40.800: DEBUG/Zygote(33): Process 339 terminated by signal (11)
09-01 07:20:40.810: INFO/ActivityManager(61): Process mogoweb.browser.app (pid 339) has died.

从NDK r5b开始,增加了调试的支持,引入了ndk-gdb脚本,可以单步调试程序。在单步调试了hello-jni后,欣喜若狂,以为结束了之前用log调试代码的痛苦日子。但在浏览器项目中使用ndk-gdb,却死活无法调试,至今都不明白是因为程序太大,还是因为程序中有多线程的代码导致的。

NDK r6给我们带来了一个惊喜,那就是ndk-stack工具,其作用就是将上面的天书翻译成我们能懂的描述。下面就看看ndk-stack是如何使用的吧。

首先,要求动态链接库带调试信息(注:并不要求在模拟器/设备中的动态库带调式信息,放心的strip掉调试信息)。如果是用的ndk-build编译native代码,在$PROJECT_PATH/obj/local/<ab>下就有,<ab>代表设备的ABI(比如,缺省就是armeabi)。如果是用的cmake编译native代码,需要将CMAKE_BUILD_TYPE定义成Debug,判断是否编译了带调试信息的版本,可以检查最后的编译命令有没有带-g参数。编译出的so通常位于$PROJECT_PATH/libs/<ab>下。

接下来输入如下命令,指定带调式符号的so所在的路径(用$SYMBOL_SO_PATH指代):

adb logcat | ndk-stack –sym $SYMBOL_SO_PATH

下面就是之前的一段天书翻译出来的结果:

********** Crash dump: **********
Build fingerprint: ‘generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys’
pid: 339, tid: 347  >>> mogoweb.browser.app <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr bbadbeef
Stack frame #00  pc 002d6ef0  /data/data/mogoweb.browser.app/lib/libmogowebcore.so: Routine Chrome in /home/alex/webkit/android2.3/src/third/WebKit/Source/WebCore/page/Chrome.cpp:67

对比当初调试浏览器代码,为了定位程序崩溃的位置,从代码入口开始一路printf,这无疑是一个重大的进步。