因爲業務裏涉及到 js 和 c++ 互相調用,爲了調試方便,研究下如何在 vscode 裏混合調試 c++ 和 js 代碼。node
效果以下, 代碼見 github.com/hardfist/cp…ios
在講混合調試以前,先簡單介紹下 vscode 下 c++ 的開發和調試, 後續全部都是在 Mac OS 環境下操做的。c++
安裝 c++ 套件 c++ extensiongit
安裝 lldb 套件 vscode-lldbgithub
確認安裝 clangweb
$ mkdir helloworld && cd helloworld && code .
複製代碼
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};
for (const string& word : msg)
{
cout << word << " ";
}
cout << endl;
}
複製代碼
此時藉助 c++ 插件的 intellisense 功能咱們就能夠自動補全了chrome
$ clang++ helloworld.cpp -o helloworld --std=c++11 // 由於使用了c++11語法,所以須要--std=c++11
複製代碼
爲了不每次修改代碼都須要手動輸入編譯指令,咱們能夠建立編譯 task 經過 Terminal > Configure Default Build Task 就能夠新建編譯 task,此時會有一些備選項,咱們這裏選擇 C/C++ clang++ build active fileshell
默認生成以下配置json
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-std=c++11", // 本身配置,支持c++11
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
複製代碼
默認生成的配置不支持 c++11,須要咱們自行配置 - std=c++11, 支持 c++11 的編譯。websocket
支持完編譯後咱們就能夠繼續進行調試,建立 launch.json,添加配置,選擇 c++ 啓動 (或者使用 lldb)
修改 program 爲當前文件對應的 bin 文件, 修改後配置以下
{
// 使用 IntelliSense 瞭解相關屬性。
// 懸停以查看現有屬性的描述。
// 欲瞭解更多信息,請訪問: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) 啓動",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
}
]
}
複製代碼
此時在 helloworld.cpp 裏添加斷點,點擊 debug 按鈕既能夠進入調試
相比於 c++ 的調試,js 就簡單不少, 添加一個 launch.json 便可,選擇 Node.js: Launch Program
修改 programe 爲當前文件,修改後配置以下
{
"name": "Launch Program",
"program": "${fileDirname}", // 調試當前選中的文件
"request": "launch",
"skipFiles": [
"<node_internals>/**" // 默認跳過node內部的js文件
],
"type": "pwa-node"
},
複製代碼
由於 c++ 和 nodejs 走的是不一樣的調試協議,所以很難經過一個 configuration 來調試二者。 咱們以 node 官方的 example github.com/nodejs/node… 看看如何進行混合調試
"scripts": {
"start": "node index.js",
"build:dev": "node-gyp -j 16 build --debug", // 編譯帶上debug信息
"build": "node-gyp -j 16 build",
"rebuild:dev": "node-gyp -j 16 rebuild --debug",
"rebuild": "node-gyp -j 16 rebuild",
"clean": "node-gyp clean"
},
複製代碼
調試程序前,咱們須要預先編譯好能夠 debug 的 addon,所以咱們建立一個 preLaunchTask,選擇 rebuild:dev, 其負責編譯一個能夠 debug 的 addon 版本
咱們新建立一個啓動 node 的 launch,不過咱們這裏使用 lldb 來啓動 node, 配置以下
{
"type": "lldb",
"request": "launch",
"name": "lldb:node",
"program": "/Users/yj/.nvm/versions/node/v12.16.1/bin/node", // 指向node入科
"args": ["examples/addon/index.js"], // 指向js入口
"cwd": "${workspaceFolder}"
},
複製代碼
此時咱們啓動 lldb:node 就能夠進入 node 的 addon 進行 debug
這裏存在的問題在於,咱們這裏其實是使用 lldb 來調試 node 程序 (此時的 addon 其實是一個動態庫),lldb 實際上對 js 的調試是無感知的,所以咱們這樣實際是沒法調試 js 的,在 js 裏打下的斷點也沒法進入。
實際上 node 的 js 裏的調試功能其實是經過 chrome debugger protocol 協議來實現的,所以咱們只須要啓動 js 的時候,開啓 inspector 協議就而後就能夠 attach 到 js 上進行調試。 修改配置,開啓 inspector 協議
{
"type": "lldb",
"request": "launch",
"name": "lldb:node",
"program": "/Users/yj/.nvm/versions/node/v12.16.1/bin/node",
"args": ["--inspect-brk","examples/addon/index.js"], // 開啓inspector協議
"cwd": "${workspaceFolder}"
},
複製代碼
此時咱們從新啓動 lldb:node, 發如今終端出來個 websocket 地址
此時有實際上有兩種方式來調試 js 了
此時咱們雖然能夠在 chrome 裏調試 js,在 vscode 裏調試 c++,可是來回穿梭仍然不夠方便
實際上當 node 開啓 inspector 協議的時候,不只能夠經過 ws attach 到 node 的 js 上,實際上也能夠經過 http:port attach 到 js 上。實際上咱們的 ws 地址也是從這個 http:port 獲取來的 nodejs 在開啓 inspect 的時候默認會啓動一個 inspect server,其地址爲http:127.0.0.1:${inspect\_port}
, 其 inspect_port 默認爲 9229,固然也能夠經過 node --inspect-brk --port:${inspect_port}
來指定其端口。 其暴露了一個接口/json
, 經過該接口便可得到其對應的 websocket 地址
下面咱們來經過 vscode 來調試 js,首先建立一個 launch 任務,此時咱們選擇 Node.js: attach
咱們選擇經過 port 來 attach 到 js 上,配置以下
{
"type": "node",
"request": "attach",
"name": "node:attach",
"port": 9229, // 綁定到node.js默認的inspect的端口
"skipFiles": [
"<node_internals>/**"
]
},
複製代碼
此時咱們只須要啓動 lldb:node 啓動調試,其會自動的中止在第一行 js 代碼上。這樣咱們就實現了在 vscode 裏混合調試 c++ 和 js
藉助於 vscode 的 launch 的 compound 功能,咱們甚至能夠避免手動的切換 debugger,達到真正的一鍵調試,配置以下
"compounds": [
{
"name": "node_c++",
"configurations": ["lldb:node","node:attach"]
}
]
複製代碼
這樣咱們點擊 node_c++ 功能就能夠實現一鍵調試