一、debugger 语句调用任何可用的调试功能,例如设置断点。 如果没有调试功能可用,则此语句不起作用。
语法
debugger;
JavaScript如何实现debugger
一、debugger的实现依托于引擎、系统和硬件,计算机操作系统和CPU在设计之初就支持了debugger的能力,不同语言和平台的debugger实现机制不同。想要进一步了解debugger,首先需要知道代码是如何在计算机(机器)上跑起来的。
debugger原理
一、剖析cpu或者操作系统如何实现debugger,涉及到计算机硬件、组成原理以及汇编语言等知识范畴。
编译型语言
中断
一、cpu指令集规定了cpu可以执行什么指令,每种指令需要提供什么样的操作数,不同类型的cpu会有不同的指令集。指令集会按照执行顺序不间断执行,但是程序在运行过程中不免要处理一些外部消息比如网络请求、异常、io读写操作等,所以cpu设计了中断机制,cpu每执行完一条指令就会去看下中断标记,是否需要触发中断机制。
INT指令
一、INT指令是cpu中用来引发中断过程的指令,中断指令有对应的编号,不同的编号对应不同的处理程序,记录编号和中断处理程序的表叫做中断向量表。其中INT3(即3号中断)用来触发debugger。
二、调试器将INT3当做软件中断指令来用,当在可执行文件中的某一位置加断点的时候,调试器会把断点处指令编码的第一个字节替换成INT3指令的编码。当程序执行到INT3,会向调试器申请系统调用权,此时调试器获得cpu控制权,同时也可以获取相应的环境数据来做调试。
三、在需要恢复断点的时候再将被替换掉的指令编码替换回去即可完成。综上,可执行文件的debugger最终依靠的是cpu的中断机制来实现。
解释型语言
一、编译型语言因为最终将会转换为机器码在操作系统上执行,所以要利用cpu和OS的中断机制和系统调用来实现debugger。但是解释型语言有自己的解释器(自己实现代码的解释执行),实现debugger也相对简单一些,不需要cpu的3号中断。
二、解释型语言通过插入一段代码来实现断点,支持环境数据的查看和代码的执行,当释放断点时解释器能够继续往下执行。
三、像js等脚本语言可以通过debugger语句实现断点,但是断住之后如何获取环境数据则需要debugger客户端来实现,常用的debugger客户端有chrome devtools、vscode debugger等等。
四、在chrome devtools中,V8引擎会把设置断点、连接请求、获取环境信息以及执行脚本的能力通过socket暴露出来以提供调试协议,要实现debugger,就要遵循并对接引擎的底层协议。
V8 debug protocol
一、这份协议中列出了实现debug相关的socket信息以及各请求/响应体的参数类型,非常详尽,我们可以根据所需查看一部分协议内容:
设置断点请求:
{
"seq":117,
"type":"request",
"command":"setbreakpoint",
"arguments": {
"type":"function",
"target":"f"
}
}
{
"seq":118,
"type":"request",
"command":"setbreakpoint",
"arguments": {
"type":"script",
"target":"test.js",
"line":100
}
}
清除断点请求:
{
"seq":117,
"type":"request",
"command":"clearbreakpoint",
"arguments": {
"type":"function",
"breakpoint":1
}
}
{
"seq":118,
"type":"request",
"command":"clearbreakpoint",
"arguments": {
"type":"script",
"breakpoint":2
}
}
{
"seq":117,
"type":"request",
"command":"continue"
}
{
"seq":117,
"type":"request",
"command":"continue",
"arguments": {
"stepaction": "next",
"stepcount": 5
}
}
通过node调试js代码
一、chrome和nodejs底层都使用了V8引擎,因此除了在chrome devtools上调试js代码之外,也可以直接使用node cli调试。
调试方式
有多种方式可以连接到nodejs inspector服务器(nodejs调试器):
- node cli
- devtools
node cli
一、一种是通过node cli,使用 inspect 指令引擎会临时搭建一个websocket服务器用来监听debugging客户端,其调试原理就是遵循了v8的debug protocol。devtools
一、另一种方式可以使用chrome提供的专门用来调试nodejs的devtools,前提是需要在devtools中配置好nodejs服务器对应的地址(host)和端口号(port)。
此外,对于上一节中提到的v8引擎中的Ignition解释器和TurboFan编译器分别对js代码执行了不同的处理(分别转换为字节码和机器码),也可以通过nodejs指令运行查看。node --print-bytecode test_demo.js
node --print-code test_demo.js