开启V8的JavaScript调试服务

Posted on July 29, 2016

V8的Javascript调试服务就是一个本地的Socket连接,嵌入V8的程序通过这个本地连接发送JSON字符串协议内容,与前端的调试工具进行交互。前端的调试工具通常是Chrome自带的开发者工具窗口,也有一些实现了V8调试协议的IDE,比如WebStorm,VSCode等。具体的调试协议内容可以参考这里:https://github.com/v8/v8/wiki/Debugging-Protocol

然而V8默认并没有开启JavaScript调试服务,在嵌入V8到自己的应用程序后,不能断点调试JS会严重影响开发效率,因为你就只能用输出log的原始方式来调试。其实旧版本的V8是自带JS调试服务的,只是因为Chrome没有用到这个模块,在大约是 3.26 版本之后就移除了。大家可以检出旧版本的v8代码库找到debug-agent.*文件就是了。但是V8里的DebugAgent引用了大量内部其他模块,想直接用还是很费劲的,我花了点时间把这块的代码已经精简抽离出来了。放在了:https://github.com/domchen/V8Performace/tree/master/src/debug

其中主要的是 DebugAgent 这个类。另外两个Socket和Log是看名字就知道是干嘛用的,可以替换自己项目里的对应类。DebugAgent 的用法很简单,在初始化V8环境后,执行如下这一句就可以了:

DebugAgent::Enable("MyApp", 5959, true);

DebugAgent::Enable 方法的三个参数含义分别是:

  • hostName: 应用程序的名称,最终会显示在调试协议的头里。
  • port: 调试协议要监听的本地端口。
  • waitForConnection: 是否阻塞程序等待调试工具连接,设置为true可以让要执行的JS代码在第一行断点。

具体的使用示例可以参考前面发的github项目里的Main.cpp文件。

到这里程序里的V8调试服务就已经开启了。现在还需要一个前端的可视化调试工具。最好用的调试工具当然是Chrome自带的开发者工具啦,可是Chrome的远程调试只支持Android,并不支持这种自己嵌入的V8调试。好在我们可以复用NodeJS的调试利器Node-Inspector。Node-Inspector把Chrome的开发者工具做成了独立的浏览器应用,对它进行一下改造,去掉专门为NodeJS设计的接口就可以做为通用的V8前端调试工具。这部分脏活累活显然我也干完了。大家只要用npm在线安装一下我封装好的命令行工具v8-inspector即可。(NPM是NodeJS的包管理器,如果不清楚使用方法,请自行谷歌。)安装命令:

npm install -g v8-inspector

然后只要简单的在命令行执行:

v8-inspector

命令,然后它就会自动打开一个Chrome浏览器窗口。默认URL是: http://127.0.0.1:8888/?port=5959。如果之前嵌入V8的程序已经启动并在阻塞等待中,这时候你应该就能直接看到那个程序里的JS文件列表,并断点在第一行了。如果程序是后启动的,没关系,F5刷新一下浏览器标签即可。URL里的 port=5959 就对应你之前给 DebugAgent::Enable 传入的 port 参数值。要修改这个端口,例如改为7878,执行下面的命令即可:

v8-inspector --debug-port=7878

你同时也可以改为监听远程的ip地址,执行下面的命令:

v8-inspector --debug-port=7878 --debug-host=192.168.1.29