现在的位置: 首页 > 综合 > 正文

福音!JS脚本可视化调试支持——基于Google v8引擎的脚本调试

2013年10月03日 ⁄ 综合 ⁄ 共 5139字 ⁄ 字号 评论关闭

有些截图没传上来,可以在这里看点击打开链接

--------------------------------------------前言----------------------------------------

相信这是一个对公司技术而言比较激动人心的话题。首先声明:我不是标题党!

难得有一个双休的周末,总算有时间能静下来研究点东西了。

想到现在项目开发中遇到的一些问题,最令人头疼的无疑是JS脚本的调试问题了。相信这个问题也是目前公司大部分技术痛恨的问题吧。大把大把的时间浪费在一些诸如大小写写错,少个标点符号之类的简单问题,而且只能靠printn多位置输出结果来缩小错误查找范围(有同感的童鞋们一定要顶哦!)。

上周刚写过一篇关于跨平台的文章《搭建跨平台的统一C++代码工程方案——跨平台篇》。看过的童鞋们应该记得文章中提到过关于Google
v8
提供的Eclipse插件,可以用来调试JS脚本。没错,它是真的,而且是强悍的!这两天专心钻研了下v8,总算了解了使用方法和一些内部原理机制。并且能够正常调试,也尝试移植到我们目前项目的代码中成功运行了。所以发此文章把一些学习心得和大家分享下。欢迎大家共同探讨。

 

--------------------------------------------为什么选择Google v8----------------------------------------  

关于在调试脚本上大量的时间浪费,我认为主要原因归结如下:

1.脚本语言本身的灵活性导致了不严谨性,且没有编译器的排错支持;

2.习惯性的手工写脚本,没能充分地利用IDEauto-complete功能;其实VSEclipse之类的IDE都提供了intelligent代码解析功能。只要配置恰当,是可以让IDE帮你自动补全你想输入的已经定义过的名字的(个人觉得VS+VAaoto-complete是最好用的)。

3.最致命的问题还是由于没有调试器的支持。

有些童鞋也许要反驳了:新的IE浏览器,Chrome浏览器,FirefoxFirebug都支持JS脚本的调试功能,而且很强大了。的确是这样的,没错。不过我在这里的讨论的是不依赖浏览器的JS脚本。做Web开发的应该比较了解,web应用程序中,JS都是由各个浏览器去解释执行的。每个浏览器都内置一套解析JS脚本的引擎。例如:FirefoxSpiderMonkey(我们目前服务器端和SPII引擎的JS脚本部分就是用该引擎解释执行的),Google
Chrome
v8(我们本次讨论的主角)。所以,很自然的,各个浏览器开发商都可以基于自己的这套引擎在自己的浏览器内潜入JS的调试环境。毕竟JS主要还是用于Web开发的脚本语言。但是随着技术的发展,现在JS已经逐渐被应用到Web之外的众多领域。我们公司就属于其一,在非web的游戏开发领域,确实比较前卫了。我们的大部分项目底层都是用C++实现的,用SpiderMonkeyJS脚本嵌入工程用作上层逻辑开发。现在的问题是:没有浏览器的支持,如何去调试JS脚本呢?虽然基于开源的引擎,理论上是可以开发一套自己的调试器,作为插件嵌入到IDE中的。但是这样做技术难度比较大,而且做出来也不一定能在短时间内达到稳定实用。但是如果引擎的开发者已经提供了这样的好用的工具,有什么理由不直接使用呢?

之前花了点时间去寻找直接支持SpiderMonkey解析JS的调试方案,没有找到比较满意的东东。不过的确有些个人开发了一些简单的插件。只是太过简单,文档什么的都没有,也没有人提供维护,所以没有打算使用。之前早就听说Google
v8
提供了调试工具。这两天查阅了相关资料,发现确实很强大。文档虽然不算很详细,但是已经足够你使用和做一些简单的优化扩展了。链接如下:http://code.google.com/p/chromedevtools/

从文档中了解到v8是目前最快的浏览器JS引擎,貌似还有Benchmark针对FirefoxSafari的一些性能对比测试。本人目前还没有验证过,既然Google都这么说了,我就信了吧-.-#。通过看他们的一些内部机制介绍,  可以看出,高效是有条件的。因为使用了hidden
class
的机制,第一次创建某个对象时会相对比较慢。因为要创建hidden class。但是重复使用时会变得异常高效。这就是复用的魔力,将需要动态查找的信息静态化。详见官方的文档。

https://developers.google.com/v8/design

Google提供了两种调试工具,一种是基于ConsoleD8(目前还没有尝试使用)。另一个是基于Eclipse的插件,提供GUI的调试。我选择的是后者。

接下来进入大家最关心的如何使用的话题了。其实官方文档里面已经说明的比较详细了,不过使用过程中还是会遇到各种各样的问题。为了让大家少走弯路,我整理了一下大致的流程供大家快速参考。好了,废话说完了~

 

-------------------------------------开发环境限制-----------------------------------

我测试的环境是Linux CentOS 6.3 + Eclipse CDT 1.5.1 

Eclipse可以在官方下载各个平台的版本

Eclipse CDT官方下载地址

这是一个比较沉重的part。既然这个插件是Eclipse的插件,自然也限制了IDE必须是Eclipse了。但是为了GUI调试的便利,忍了吧。实在不想用Eclipse的童鞋可以考虑用Console的调试器D8。不过好在Eclipse本身是跨平台的,所以平台倒是不用过于担心了。

 

-----------------------------------安装v8------------------------------

官方文档

有多种方式选择下载安装,我是直接用Git下载的。

Down下来后需要编译

编译文档

以我的环境为例,直接make dependencies后,make nativeOK了。其它环境下参考以上围挡

 

-----------------------------------插件安装-----------------------------

首先需要安装插件,打开Eclipse,菜单选择Help->Install New Software...弹出界面里点右边的Add...然后Location中输入http://chromedevtools.googlecode.com/svn/update/dev/

OK。选择插件进行安装

由于需要java VM等相关依赖项支持,如果有缺失项,请手动安装依赖项或是再添加几个自动更新的下载点

http://download.eclipse.org/releases/juno

http://download.eclipse.org/tools/cdt/releases/indigo

http://download.eclipse.org/linuxtools/update

官方参考:

http://code.google.com/p/chromedevtools/wiki/HowToInstall

 

----------------------------------开始体验--------------------------------

先解释一下,Google提供的这个调试插件是remote调试插件。也就是说,调试器和被调试应用程序是通过网络通讯的方式传递调试信息的。所以调试器和被调试程序实际上是两个进程。也正因为如此,调试时需要有些同步加锁的过程。不过Google都已经封装的比较简化了,使用起来还是比较简单的。而且还支持直接和Chrome浏览器通讯调试web程序,详细请参考

http://code.google.com/p/chromedevtools/wiki/DebuggerTutorial

先用官方提供的示例体验一下调试过程吧。

先进入v8的编译目录下的输出路径(v8/out/native/)。里面应该能看到一个lineprocessor的文件,这是v8已经编译好的一个sample程序。先在该目录下新建一个test.js文件(文件名可以随意取)。文件内容如下:

function ProcessLine(line) {

        var a = 10;

        var b = 11;

        c = a + b;

 

       // 这行目前是必须的,上面几行是我为了测试显示变量值随意加进去的,可以自行改

        returnline.toUpperCase(); 

}

保存后在控制台执行lineprocessor程序

./lineprocessor test.js -p 9222--main-cycle-in-cpp --callback

如果是直接执行程序(不通过控制台),则需要加入参数 test.js -p 9222--main-cycle-in-cpp --callback

9222是端口号,也是可以自己改变的。

该程序会循环执行你刚刚编写的脚本,从控制台获取一行输入,转成大写后输出。

现在先不用管程序,准备开始启动调试器。先打开Eclipse,选择菜单Run->Debug Configurations

按下图中的窗口所示,选中Standalone V8 VM,再在左上角单击New configuration图标。新建一个调试配置项。配置按图中所示


配置完后单击右下角的Apply按钮,然后单击右下角的Debug按钮开始挂接。挂接完成后注意看Eclipse左边Project
Explore
窗口

刚才配置的New_configuration想被动态添加到这里了,连相关的脚本都被copy过来了(所有被执行到的脚本都会被拷贝到这里,这不禁让我想起当年调试lua的时候似乎也是类似的机制)。这时候在Eclipse中双击test.js打开脚本编辑。先尝试暂停程序的执行吧。单击Eclipse上面的暂停按钮,程序停下来了。记得要把右上角的视图切换为Debug视图。 然后打开 打开Expressions窗口。在窗口中随意输入一些JS脚本试试。比如试试下面的:

神奇吧。不过这还不算什么,下面试试我们都比较喜欢的断点功能。这里需要注意的是一定要将断点类型切换为v8 breakpoint才行。在菜单Run里面选择Breakpoint
Types->Chrome/V8breakpoints

然后在Eclipse代码窗口中左边空白处你要加断点的行双击

左边那个蓝色的点就是断点。

接下来让程序执行到断点处吧。(记得先恢复暂停的程序执行,用F8或者单击上面的按钮)。打开被调试程序运行的控制台,随便输入一些文字回车,断点断到了!然后把鼠标停留在你想要查看的变量上面就会显示相应的变量的值,简单类型到复杂类型的值都能看到!更神奇的是还能看js的调用堆栈。这里因为只有一个js函数调用所以没有堆栈信息。更多调试细节参考:

http://code.google.com/p/v8/wiki/AddDebuggerSupport

http://code.google.com/p/chromedevtools/wiki/EclipseDebuggerFeatures

 

-----------------------展望Google v8在项目中的应用-----------------------

既然v8这么powerful为什么不用它直接取代SpiderMonkey呢?我之前也有这个疑问,后来据说因为使用了v8的客户端在发布Apple程序的时候验证会失败。具体原因有好几种说法,我也没见到过,所以暂且不讨论。不过我个人认为总会有办法解决这个问题的。但是对于服务器端开发来说不受这个限制,所以我打算先移植到服务器端使用。今天已经尝试成功了,改动也不会很大。但是带来的便利是可想而知的,姑且不论效率的改善。关于v8SPII引擎的整合还得先过了Apple验证这关才有可能做。不过如果能早日一统江山相信对大家都是一个福音啊!

 

发现写的有点多了。关于具体如何把v8嵌入到项目中使用,和一些v8的使用、优化等问题我想留到下次有时间再来写了。大家有兴趣也可以多参考下官方的文档。也可以和我一起线下交流。最好的学习办法是文档结合sample代码来看(sample源码路径在v8/samples)。相信上手很快的。 
                                                                                                      

 

抱歉!评论已关闭.