存档

‘技术’ 分类的存档

计算机不存在灵异事件

2009年8月1日 2 条评论

再把这条铁律拉出来一次。

今天碰到了一个bug,服务器在运行时会core dump在一个很灵异的地方,排除这个错误的过程,以及最后发现的错误结果很具有典型性,所牵涉到的技术也很多,拿来作为Linux调试的课程挺好的。:-P

整个里面假设读者已经知道怎么用gdb,如果不知道,请参见GDB Manual

首先,很幸运的是,这个问题是可以很容易重现的,而且更重要的,有core dump。
拿到core dump之后,惯例是查看一下调用栈:(为了避免泄漏商业秘密,所有函数名,文件名什么的都用foo啊,bar啊,foobar啊,blabla啊等等代替)。

(gdb) bt
#0 0x000000eb in ?? ()
#1 0x3aa1d941 in ?? ()
#2 0x000001f8 in ?? ()
#3 0x080cf888 in foo (range=10000) at foo/foo.c:18
#4 0x080c1f29 in bar () at bar/bar.c:423
[....]

(gdb) info f 0
Stack frame at 0xbfc42548:
eip = 0xeb; saved eip 0x3aa1d941
called by frame at 0xbfc4254c
Arglist at 0xbfc42540, args:
Locals at 0xbfc42540, Previous frame's sp is 0xbfc42548
Saved registers:
eip at 0xbfc42544

(gdb) f 3
#3 0x080cf888 in foo (range=10000) at foo/foo.c:18
18 return ((u32)random()) % range;

相当的灵异,栈上的0,1,2都是,一个返回地址怎么可能是0x1f8,而且,core dump的原因是因为eip跑飞到了0xeb。到frame 3的时候看起来正常了,但是出错的地方在random这种简单的库函数上。不过既然frame 3往下的部分都是好的,我们有理由认为栈并没有被搞坏。因为GDB在显示调用栈的时候可能会把一些不正确的调用栈也显示出来,我们干脆直接看内存:

(gdb) x/10w $esp
0xbfc42544: 0x3aa1d941 0x000001f8 0x080cf888 0x09582930
0xbfc42554: 0x0833f038 0xbfc42678 0x080c1f29 0x00002710
0xbfc42564: 0x0823747f 0xb7ca168c

看加粗的部分:这里就是frame 3返回地址,而上面的东西,就是bt显示出来的frame 1和frame 2了,而frame 0就是当前的eip了:它跑飞到了0xeb。

GDB果然在显示栈的时候做了手脚。

OK,我们反汇编看看这个返回地址,到底干了什么:

(gdb) disassemble 0x080cf888
Dump of assembler code for function _Z6foom:
0x080cf85c <_Z6foom+0>: push %ebp
0x080cf85d <_Z6foom+1>: mov %esp,%ebp
0x080cf85f <_Z6foom+3>: push %ebx
0x080cf860 <_Z6foom+4>: sub $0x4,%esp
[…]
0x080cf87a <_Z6foom+30>: movl $0x0,0xfffffff8(%ebp)
0x080cf881 <_Z6foom+37>: jmp 0x80cf893 <_Z6foom+55>
0x080cf883 <_Z6foom+39>: call 0x8051f90
0x080cf888 <_Z6foom+44>: mov $0x0,%edx
[…]
0x080cf899 <_Z6foom+61>: pop %ebx
0x080cf89a <_Z6foom+62>: pop %ebp
0x080cf89b <_Z6foom+63>: ret
End of assembler dump.

看起来也没干啥,继续看调用的地址是啥吧:

(gdb) disassemble 0x8051f90
Dump of assembler code for function random@plt:
0x08051f90 : jmp *0x833f140
0x08051f96 : push $0x1f8
0x08051f9b : jmp 0x8051b90 <_init+24>

有点意思啊,random@plt,PLT是什么?PLT是Linux ELF格式可执行文件当中的一个部分,称为Procedure Linkage Table。PLT是程序为了实现Linux共享库的动态迟绑定(Lazy Binding)而引入的一种机制。关于 ELF格式、PLT,和下面要提到的GOT(Global Offset Table)的资料,可以参见下面这些链接:
The ELF Object File Format: Introduction
http://www.linuxjournal.com/article/1060
UNIX ELF File Format (PPT)

好了,言归正传,就算你不知道PLT,你也可以继续往下看。最土的办法,既然jump到一个地方,就看看这个地方是什么吧。

(gdb) p/x *0x833f140
$6 = 0x8051f96

显然这个重新跳回到了PLT当中,看下面:

(gdb) disassemble 0x8051f96
Dump of assembler code for function random@plt:
0x08051f90 : jmp *0x833f140
0x08051f96 : push $0x1f8 // 这是栈上的 0x1f8
0x08051f9b : jmp 0x8051b90 <_init+24>

又一个jmp,这次jmp到了什么地方呢?

(gdb) disassemble 0x8051b90
No function contains specified address.

这是怎么回事?因为没有对应的符号,或者这一段代码不在.text里面。不过我们还可以用其他的方法看到指令:

(gdb) x/10i 0x8051b90
0x8051b90 <_init+24>: pushl 0x833f03c // 这是栈上的另一个东西的来源
0x8051b96 <_init+30>: jmp *0x833f040
0x8051b9c <_init+36>: add %al,(%eax)
0x8051b9e <_init+38>: add %al,(%eax)

又有一个jmp,继续。

(gdb) p/x *0x833f040
$7 = 0xeb

怎么会这样?这个指针被覆写了,Jump到了0xeb,然后就core了。

看08833f040这个地址,属于GOT(Global Offset Table):

(gdb) x/10w 0x833f040
0x833f040 <_GLOBAL_OFFSET_TABLE_+8>: 0x000000eb 0x00000002 0x00000006 0xb7f4401c
0x833f050 <_GLOBAL_OFFSET_TABLE_+24>: 0x08051bd6 0xb7d8e9b0 0xb7d85260 0x08051c06
0x833f060 <_GLOBAL_OFFSET_TABLE_+40>: 0xb7d32ae0 0xb7da88d0

我们从GOT头上开始看:

(gdb) x/10w 0x833f040-8
0x833f038 <_GLOBAL_OFFSET_TABLE_>: 0x00000000 0x3aa1d941 0x000000eb 0x00000002
0x833f048 <_GLOBAL_OFFSET_TABLE_+16>: 0x00000006 0xb7f4401c 0x08051bd6 0xb7d8e9b0
0x833f058 <_GLOBAL_OFFSET_TABLE_+32>: 0xb7d85260 0x08051c06

仍然说Lazy Binding相关的东西,如果你了解ELF的Lazy Binding,你会知道GOT的前面四个字是特殊的,而其中的GOT+8的地方是_dl_runtime_resolve,而上面的最后一个jmp就是跳到这里。但是,这里却变成了0xeb。

错误的原因找到了,但是,究竟是谁干的?我们知道gdb有一个很好的feature叫做watchpoint,这个在VS当中被叫做Data Breakpoint。它们的本质是一样的,都是通过硬件来实现对某个地址的监控,你可以设定当这块内存被读、写、或者被访问(包括读写)的时候触发该断点。很好,我们就在这里加上一个watchpoint。注意watchpoint的语法,你需要在地址前面加一个*。

我们重新启动服务器,然后attach到这个进程,对出现错误的地址 0x0833f040加了watchpoint。为什么可以这么做?因为GOT在内存当中的位置是固定的,我们知道,无论你第几次启动一个程序,GOT都会被加载到同一个地址。

(gdb) watch *0x0833f040
Hardware watchpoint 2 added

然后继续执行

(gdb) c
Continuing.

然后,坐到一边喝茶去吧,等待你看到gdb被断进去。
然后,终于,等到了。

Hardware watchpoint 2: *137621568

Old value = -1208695104
New value = 235
CFoo::foobar (this=0xb1df5810) at foo/foobar.c:477
477 blablabla_func(0, sth->data.id, tmpData);
Current language: auto; currently c++

好了,我们看看这个时候的GOT:

(gdb) x/w 0x833f040
0x833f040 <_GLOBAL_OFFSET_TABLE_+8>: 0x000000eb

这个值的的确确被修改了,那么,我们看看栈。

(gdb) bt
#0 CFoo::foobar (this=0xb1df5810) at foo/foobar.c:477
#1 0x0812fa69 in CFoo::doSomthing(this=0xb1df5810, action=0xbfb93378, event=0xbfb934d0) at foo/foobar.c:1100
[...]
#10 0x08067a60 in main (argc=0, argv=0x3aa1d95a) at server.c:1289

很好,这是我们的代码,过去看看:

对应代码:
LPSOME_DATA_TYPE tmpData;
u64 some_array[MAX_SOME_ARRAY_SIZE];
size_t array_sz = MAX_SOME_ARRAY_SIZE;
[...]
tmpData->iRet = 0;
tmpData->iField01 = someVar;
tmpData->iField02 = SOME_CONSTRANT; // iField02的offset是8,也就是结构的第三个成员。
tmpData->iId = some->unit_id;
foobar(); // line 477

(gdb) p tmpData
0x833f038

OK,因为代码已经被处理过,所以逻辑可能看的不是很清楚,但是很明显,在这里,问题在tmpData,这是一个指针(请参见类型,但是变量名竟然没有任何的表明这个是个指针),没有初始化就用了。非常非常的巧合,这个变量所在的地方正好是GOT的地址,然后,在对iField02变量赋值的时候,_dl_runtime_resolve的地址被覆盖掉了。

至此,凶手已经找到了,但是这个给我们什么启示呢?

计算机没有灵异事件。

标签: , , ,

[视频]第六感——可穿戴式手势控制人机界面

2009年3月14日 3 条评论

WUW / sixthsense – a wearable gestural interface

啥都不说了,这个真是酷毙了。

 

标签: , ,

智能手机引出的一点乱七八糟的看法

2009年2月26日 2 条评论

最近同事当中的智能手机越来越多,基本上可以分成三大阵营:
Windows Mobile、iPhone和Nokia S60,偶尔有几个嵌入式Linux但是还没成气候,Google的Andriod还没发现。
当然张得很像智能机的山寨机也有,不过它们不算。

智能手机有个共同点,就是屏幕大而且大部分都是触摸屏。
大家都很追求大的屏幕和高分辨率,毕竟大屏幕+高分辨率看起来就是爽,iPhone就是个例子。
但是屏幕做的太大,手机也会跟着做的很大,就不能很容易的放在口袋里了。
于是有了Nokia的可折叠的屏幕。
不过我觉得,屏幕能折两折,四折?最后拿出来一堆片片,想看短信要先拼图。
其实干嘛非要把屏幕做在手机上?把屏幕从手机上分离,用其他的方式做显示,然后手机本身的计算部分就可以做的很小。
问题就是把屏幕从手机上拿下来之后怎么显示的问题。
一个方法是使用某种手段直接把映像投射到眼睛里,让人感觉前面仿佛有一个屏幕。当然可能的话直接和视神经交互也可以。
前面那种东西目前有个叫iWear的公司有做,叫做Video Glasses。不过这个东西戴上就看不到前面的东西了,不能一边走路一边用。
直接和视神经交互的东西不知道有没有,有的话应该也只是停留在实验室里面。
最好的方法是有一种眼镜,可以将计算机图像叠加到真实图像上面,这样可以弄很多东西出来,比如看到一个人的脸就会显示他的名字,而且不用拿一半的生命来换。

然后就这这样的话怎么输入。
反正看东西不用掏手机了,自然不能把输入做在手机上了,没事谁掏手机啊。
替代的可以用语音,或者手势。
比如我在面前画个M就打开地图,当然你也可以设置成拨麦当劳的外卖电话。
或者在手上画个圈就出现一个表。这样带三个表只要画三个圈就行了。
必要的时候也可以调出键盘,通过眼镜让你面前仿佛有一个键盘一样。
然后通过某种空间跟踪的东西跟踪十根手指的空间位置,模拟按键。
最好还有模拟的力反馈和触觉,比如手放在F和J上面可以摸到一个突出的小东西之类的。
应该可以直接和手上的皮肤神经末梢交互吧……

最后就是电源。总不能到处都是电池吧。
太阳能吧,身上贴一层防晒膜,其实是太阳能电池板。你要是看见一帮人穿着比基尼摆成大字形晒太阳,没准人家正在为手机充电。
或者直接烧ATP怎么样?这个ATP叫三磷酸腺苷,不是职业网球联合会。理论上取之不尽直到你挂掉,而且顺便可以加快新陈代谢。

嗯。我在胡言乱语……

标签: ,

Follow up: 可用于OpenInkpot的Trac扩展:TranslatedPages

2009年1月26日 2 条评论

继续上一篇当中提到的扩展。

http://trac-hacks.org/wiki/TranslatedPagesMacro

扩展目前实现成Macro的形式,但是硬编码了支持的语言类型,很丑。

下一步继续扩展,需要提供一个Web UI来管理需要支持的语言列表,然后还要加上权限控制,估计要写成Plugin了。

OpenInkpot的中文BBS

2009年1月18日 没有评论

由一路书香提供。
http://bbs.mobread.com/forum-31-1.html

OpenInkpot项目致力于为基于e-ink(电子墨水)技术的设备创建自由、开源的基于Linux的系统。

这段蹩脚的说明一看就是我翻译的……

其实是前段时间OpenInkpot开始启动翻译项目的时候,我就顺手把上面几篇用户手册翻译了一把,看起来还有点用处。其实Wiki的中文化只是其中很小的一部分工作,更多的中文化的工作还是需要很多志愿者的贡献。本来OpenInkpot有一位中国的贡献者Wenjie Zhang,但是据dottedmag(OpenInkpot项目的Lead)讲,在7月份失踪了,鉴于他在四川读书,所以我们只能祈祷他现在安全。

目前这段时间正在研究Trac的结构,希望可以写一个patch或者plugin来自动枚举所有的翻译语言版本,并且用好一点的方式显示出来,比如现在的 [en, zh] 这种模式实在很难让普通用户了解这个就是英文版和中文版。如果换成 [English, 简体中文] 这种模式,会好一点。但是不能要求所有的人都会说这么多语言,并且能够把名字输入正确,所以还是做一个插件,大家只要把文章翻译好,剩下的交给插件去做就好。

再说说一路书香这个网站,应该说是做的比较好的中文电子书阅读器的信息论坛,当时我在评估电子书阅读器的时候花了很多时间在这个上面,后来买了翰林也是通过这个网站牵线搭桥找到南京的代理。总之来说,推荐有兴趣研究电子数阅读器的朋友们,有空去上面看看。

标签: ,

当核电站都可以量产的时候

2008年11月11日 2 条评论

http://www.cnbeta.com/articles/69450.htm
美国洛斯阿拉莫斯实验室科学家说,能为2万户家庭提供用电的微型核电站5年内有望上市。

这个来自CNBeta的新闻,可信度先不说,会不会带来恐怖袭击也不说,2500万美元每台的定价是不是靠谱也不说,只是说这个点子就让人觉得有趣。

想想以前,大家自己要顾及自己的能源,需要自己砍柴烧饭,自己买油点灯照明;后来有了电网和电站,于是能源的生产、传输和使用就分开了,大家在使用电力完成照明和烧饭的任务之外也出现了逐渐多样化的能源使用者,出现了大量的电器可以满足大家的需要。但是这样的模式也有自己的问题。一个就是巨大的传输损耗,另一个就是电站的设计和运营仍然没有分开,所以电站的运营成本仍然需要将设计成本计算在内,而且一个设计很难复用在其他电站用来降低成本。

现在有了这种可以量产的核电站,也就解决了这样一个电站的设计和运营的问题。如果电站的设计成本可以因为复用而降低,那么部署更多的电站,实现更分布的电网也就成为可能。而购买了电站的人或者组织只要负责运营电站,所以他们也可以把更多的精力放在优化运营上面。关键是要有一个电站的标准,所有符合标准的电站都可以加入电网。于是电力这个系统也就将原来的电站细分成了电站设计公司和电站运营公司。说不定可以极大降低电力的成本,这样没准更多有趣的,但是需要大量电力的应用就可以得到商用,比如说,粒子级别的物体分解和重组?Thinking

和电力系统向对应的一个行业就是计算机行业。人们常用的隐喻就是,早年大家需要提供自己的在线应用,需要自己买机器,自己拉网线接入互联网,自己维护机器,这相当于大家自己砍柴烧火做饭的年代;后来有了主机托管,于是一部分维护成本就转移到托管商那里,并得到一定的优化从而降低成本,这相当于管道煤气烧火做饭,虽然能源的生产和分发得到了一定程度的分工,但是能源的提供方式不够通用,所以管道煤气也只能用来做做饭、顶多能用来烧洗澡水,托管也一样,这种主机通常用来托管网站,很少见到有人拿它作其他应用,比如做一些科学计算等等;再后来有了Amazon的云服务,还有Google的GAE,直接将存储和计算能力出售,而不在乎这种计算能力来自哪里,这相当于大家开始逐渐用电力通过电热炉来做饭烧水的年代,因为计算能力和存储相对更抽象,也就有人开始拿它做别的,比如做科学计算。

那接下来,如果像我想象的电力系统的未来一样,将云平台的设计和运营分开,有专门的云平台软件提供商,专门做云计算软件,运营交给其他的公司去做,如果到时候提供GAE服务的提供商和现在的托管商一样多,竞争起来,价钱说不定就会大大降低了。做软件让别人运营,这个听起来很像是某$公司的做法。


以上纯属扯淡,如有不满,敬请提出。

标签: ,

The Yet Another Blog

2008年10月5日 3 条评论

http://ftofficer.blogspot.com

这个新blog将完全集中在技术问题的探讨上,并且将以英文发布。

访问这个blog需要翻墙,方法可以参考我之前的帖子。或者可以直接在Google Reader当中添加“http://ftofficer.blogspot.com”到订阅即可直接翻墙。

标签:

Firefox 当中HTML控件无法正常显示

2008年10月3日 没有评论

今天照常上网的时候,突然发现自己的Google主页上面的所有按钮上面的文字都消失了,所有的单选按钮也都消失了。
变成了这样:

Firefox Render HTML Control Bug

这个问题最后得以解决,解决方案如下:
首先,在地址栏输入about:config,然后找到nglayout.debug.enable_xbl_forms这个配置项,如果它是true的话,把它改成false。重新启动Firefox即可。

======我是无聊的分割线======

如果你的兴趣仅限于解决这个问题,下面的查错过程请无视。

这当然是非常不爽的一件事情,于是我开始回忆在上次显示尚且完好之后我做了什么操作,但是实在想不起来上次完好是什么时候的事情了——我上网一般都是在Google Reader上面徘徊,而Google Reader上面确实没有什么显眼的HTML标准控件可以让我发现这个问题。

于是没有办法,只好开始手动排错。在重新启动Firefox,重新启动Windows,用IE访问Google主页三步之后,基本可以排除系统原因或者Google的网页本身的原因。接下来看看是不是插件的问题,那么就先从“安全模式”开始看看问题是否能够解决。于是打开Firefox在开始菜单当中的安全模式,然后把“禁用所有扩展”打勾,重新访问Google,问题依旧,因此也不是插件的问题。那么是Firefox本身程序的问题么?为了考察这个,我新建一个Profile:在命令行中输入<path_to_firefox>\firefox.exe -P,注意P需要大写,然后再弹出对话框当中选择新建配置文件之类,完成之后用这个新的配置文件启动,然后访问Google,没有问题。因此看起来问题仍然在Profile本身。

Profile当中既然不是插件的问题,那么很可能就是首选项的问题了。我们知道在每个Profile目录下面有一个prefs.js的文件,是Firefox在当前情况下的所有的首选项的值,也就是在about:config里面看到的东西。最简单的就是比较两个Profile当中的prefs.js文件。在经过了大约半个小时,尝试过数十个不同的首选项之后,发现了nglayout.debug.enable_xbl_forms这个罪魁祸首。

然后用这个key的名字来搜索,发现其实这个是从Mozilla 1.3就开始有的问题,最早可以追溯到2002年12月:

XBL-based form controls are broken and
unusable in 1.3 and trunk builds.
(bug 185612)
If HTML form controls are not appearing and functioning on HTML pages,
check ‘prefs.js’ for the line ‘user_pref("nglayout.debug.enable_xbl_forms", true);’.
NOTE: this will only affect you if you had previously set this preference
in the ‘Debug’ panel in a previous build of mozilla. Casual users should
never change any of these settings.

这个至今未关的Bug (185612)就是在讨论我遇到的这个问题。

事情还没有结束。

在我没有修改这个键值的情况下,是谁动了我的Firefox键值?

在仔细回顾了这个问题之前一天我所做的事情之后,发现嫌疑最大的是插件 XPCOMViewer 版本0.9a。在新建的Profile上面尝试,发现一旦打开XPCOMViewer的主窗口,这个键立即就被改变成了true。也许是作者为了绕过某个难解的bug吧。之后查阅XPCOMViewer网站,发现作者公布的最新开发版1.0a当中已经修复了这个问题,也许我应该给作者发一封信告诉他应该更新一下Mozilla网站上面的版本了。

最后要澄清一下,虽然0.9a有这样的问题,但是作为一个仍然在sandbox当中的项目,这个扩展已经做得相当的好用。根据作者最近的一篇文章当中所说,1.0a版本支持一个非常cool的特性:直接将一个XPCOM组件导出成为Javascript/C++/Python的代码。对于有意在Firefox平台上面做点事情的朋友,这个扩展值得推荐。

标签: ,

用google.cn做proxy访问Google的服务

2008年9月17日 1 条评论

最近玩Google App Engine,发现随着闹运会的结束,这个东西也重新不可访问了。今天偶然在SMTH的Python版上看到的。非常实用的一个方法,原始作者不可考,于是整理一下写在这里。

简单的说,Google的所有服务都是可以通过一个相同的服务器访问到,Google根据请求的URL当中的域名来决定应该定向到哪个服务。www.google.cn一样可以访问到所有的服务,例如App Engine。但是因为DNS服务器的原因,appengine.google.com会被定向到Google美国的服务器,不会去连接www.google.cn。但是事实上,如果我们能够向www.google.cn发送一个HTTP请求,其中的URL是指向appengine.google.com的,服务器一样能够帮我们中转请求,并把结果会传给我们。

要达到这个目的有两个方法,一个是修改hosts,让appengine.google.com和*.appspot.com指向到www.google.cn的IP地址。这个有两个劣势,一个是www.google.cn其实有很多个地址做负载均衡,一旦加上了hosts条目,就失去了负载均衡的好处;另一个劣势是hosts文件不支持*.appspot.com这种语法,所以只能把自己知道的appspot上的应用统统添加。

另一个方法则相对好一点,就是把www.google.cn:80设置成访问appengine.google.com的代理服务器。这种方法很好用,但是需要写PAC文件(Proxy Auto-Config,代理服务器自动配置文件)。所幸这个文件语法相当简单,因此可以直接写下面一段:

function FindProxyForURL(url, host) {
    if (shExpMatch(host,"*.appspot.com")) {
        return "PROXY www.google.cn:80";
    }
    if (shExpMatch(host,"appengine.google.com")) {
        return "PROXY www.google.cn:80";
    }
    return "DIRECT";
}

然后保存成一个proxy.pac文件。在浏览器的配置当中,把“自动浏览器配置脚本”的配置项指到这里即可。

标签: ,

说说Google的开源浏览器Google Chrome

2008年9月2日 2 条评论

Google今天在官方blog上面透露,他们“无意中”把Google自己的浏览器Google Chrome的漫画泄漏到了网上(看不懂E文的看这里)。这个漫画相当有趣,晚上发现cnbeta上面已经有人放出来了漫画的中文版,没看过的可以先看看。

说说几个吸引我的地方。因为我的经验主要是Firefox,对IE缺少研究,所以讨论也是基于对于Firefox的了解。

“现在的浏览器本质上是单线程的”

一针见血的论断,之前在研究Firefox插件的时候,发现了Firefox的这个设计缺陷(或者叫特性?)。Firefox虽然使用了多线程进行网络IO,但是界面的渲染仍然是单线程的,而这个单线程的本质原因是因为Javascript引擎是单线程的。单线程有一个好处就是编程简单,尤其对于插件来说,不需要头疼同步问题。但是单线程也有严重的问题,就如同在漫画中描述的那样,任何一个页面上的Javascript问题都会导致整个浏览器等待,表现就是界面停滞甚至死掉。现有的解决方案之一是异步模型,或者叫Event Driven的模型,例如Ajax就是对于网络IO的异步化,也有一些模拟的实现来实现Javascript的线程,比如使用SetInterval。但是因为Javascript规范缺少线程模型,引擎也很难做成多线程的,这个限制也极大地制约了浏览器和网络应用的性能和响应。

对于此问题,Google的解决方案是一个折衷:多进程。这样既不需要修改Javascript引擎,同时可以获取到并发的优点。其实我对于漫画当中对于多进程对于节省系统资源的论断持保留态度,对其他宣称的好处也是有保留的赞成,但是我承认这是一个正确的设计决定。用多进程的模式实现的浏览器,对于将来潜在的插件的实现者来说,是一个极大的模型简化。使用多线程的Javascript引擎(如果有的话),我相信带来的问题会比解决的问题更多。

多进程模型

接下来就是说另一个有趣的地方:多进程。从漫画当中透露出来的消息来看,这个多进程模型是1拖N的模式。每一个页面都将是一个单独的进程。因此我开始怀疑,Google Chrome如何实现标签页浏览。也许根本就没有实现,或者实现了一个假的。如果将标签页浏览实现在Chrome任务管理器当中,就必须有一种IPC机制来让管理器来将窗口共享给子进程来渲染,这个我还没有想到一种可以跨平台的实现方式。

Chrome任务管理器

非常cool,非常值得期待的组件,如果其功能真的如同其在漫画当中宣称的那样棒的话。

这个也是我对于Firefox最期待的功能之一。目前虽然有FireBug作为替代方案,但是FireBug仍然是内建在浏览器内部的。我希望的是一个非侵入式的任务管理器,一个独立于浏览器之外的组件来实现对于浏览器执行流程的监控。这样的好处之一就是可以在浏览器失去响应或者崩溃的时候仍然保留对于Javascript执行状况的监测。理想状况下我期望如同Windows的调试器一样,attach到一个失去响应的进程然后查看其调用栈或者执行时间,进而可以了解到浏览器各个组件的执行状况,发现引起问题的组件。

实现这种功能,需要Javascript引擎的协助。引擎必须提供一种机制来中断当前的执行流程,并能够使用某种机制将其内部状态导出。这是一个不小的工程。但是由于Google的介入,也许这个并非不可能之事。

名字和核心

Google Chrome。当我看到这个名字的时候,我就以为这个是基于Gecko的另一个版本——因为Gecko(Firefox所使用的核心)的核心组件之一就是Chrome。或者说,Firefox本身就是一个Chrome。

但是根据一些透漏的信息,Google Chrome使用的是WebKit内核——一个宣称比Gecko更快、更高效的内核。这个也比较靠谱,毕竟Google的Android上面使用的也是WebKit内核。

野心

随着浏览器的发布,Google用户联网占领桌面,并且试图逐渐替代桌面的野心昭然若揭(当然很早之前就已经是司马昭之心了)。一个中央管理组件协调各个网络应用;每个网络应用占用一个进程;可以查看任何一个应用的资源占用和响应时间;再加上从Google Doc到Google Mail的一条线的网络应用……

很好很强大的新桌面和新系统。


到了那个时候,你的所有安全,就全部寄托在了几个在网络上明文传送的Cookie。

标签: , , ,