v8从入门到入土:调试篇一(Inspector)

v8从入门到入土:调试篇一(Inspector)在安卓下做v8嵌入式开发,最头疼的莫过于调试js。 关于调试js,使用过RN的同学应该知道,以前RN调试其实是通过pc上跑手机里面同样的js,然后两边的js通过websocket进行数据通信,以达到模

在安卓下做v8嵌入式开发,最头疼的莫过于调试js。

关于调试js,使用过RN的同学应该知道,以前RN调试其实是通过pc上跑手机里面同样的js,然后两边的js通过websocket进行数据通信,以达到模拟调试的效果。但是这种模式的弊端主要有两点:第一,如果两边的js有不一致的地方,就很容易造成调试ok,但是手机单独运行就会出错;第二,手机上如果有一些通过V8内置的变量和方法,需要繁琐的把这些信息同步给PC模拟同样的效果。

这时第一时间想到的就是V8的inspector调试协议,通过调试协议去同步手机真实的js环境到devtools岂不是很完美!

然而,当深入了解时才发现,v8嵌入式开发关于调试这块的介绍和文章太少。这是v8官网的介绍 v8.dev/docs/inspec…,看了后就会发现其实没啥帮助,等于没说,V8源码里面的两个demo我也试过,发现根本跑步起来。好在有nodejs、chromium,我们可以去看他们的源码。

闲话少说,我们进入正题。

v8 Inspector是啥?

他是一套js调试协议,协议里面定义了如何同步代码、断点、函数运行结果灯等之类的调试信息,能让实现了该调试协议的client调试V8代码。chrome dev tools(后面简称为CDT)已经实现了该协议,所以我们通过chrome浏览器就能很方便的调试,不需要我们单独再实现一遍。输入的url为:chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:8082/debugger-proxy?role=chrome

实现原理是啥?

已经有了我们实现的嵌入V8的app,也有了CDT,怎么让他们两者勾搭上呢?原理其实很简单,需要一个websocket server来做消息的转发,把CDT的消息给app,把app的消息给CDT,然后你就会神奇的发现可以调试了。

websocket server放在哪一层?

server可以放的地方很多,可以放在app里面的java层,也可以放在app里面的c++层。我们则是放在PC上用nodejs来承载的,因为历史原因,我们这个server以前就存在了,这样的实现对我们来说成本是最低的(当然还有个原因是因为我对nodejs更熟悉些)。

架构图大致如下:

\

v8从入门到入土:调试篇一(Inspector)

接下来看代码:

// init 省略过的代码
std::unique_ptr<v8_inspector::V8Inspector> inspector_;
std::unique_ptr<v8_inspector::V8InspectorSession> session_;

v8_inspector::V8InspectorClient* inspectorClient = new V8InspectorClientImpl();
inspector_ = v8_inspector::V8Inspector::create(isolate, inspectorClient);

V8ChannelImpl* channel = new V8ChannelImpl();
session_ = inspector_->connect(1, channel, v8_inspector::StringView());

inspector_->contextCreated(v8_inspector::V8ContextInfo(context, 1, v8_inspector::StringView()));

// send message to v8
session_->dispatchProtocolMessage(message_view);

// send message to CDT
void V8ChannelImpl::sendResponse(int callId, std::unique_ptr<v8_inspector::StringBuffer> message) {
  // TODO
}

void V8ChannelImpl::sendNotification(std::unique_ptr<v8_inspector::StringBuffer> message) {
  // TODO
}

// java 收到消息后通过socket传给 CDT
public void InspectorChannel(byte[] params) {
	if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
		String msg = new String(params, Charset.forName("UTF-16BE"));
		if (mDebugWebSocketClient != null)
		{
			mDebugWebSocketClient.sendMessage(msg);
		}
	} else {
		String msg = new String(params, Charset.forName("UTF-16LE"));
		if (mDebugWebSocketClient != null)
		{
			mDebugWebSocketClient.sendMessage(msg);
		}
	}
}

\

在nodejs server上你可以看到这样的消息:

\

v8从入门到入土:调试篇一(Inspector)

可以看到传输的协议是json,有兴趣的可以研究下里面的细节,还挺有意思。

你在chrome里面就可以调试了,大功告成!

\

v8从入门到入土:调试篇一(Inspector)

今天的文章v8从入门到入土:调试篇一(Inspector)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/20858.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注