# 前言

下午的时候朋友问关于 VS Code Debug 时如何输入数据的问题,首先在使用 VS Code Debug 之前需要配置,网上的教程杂七杂八的,这里我简要翻译一下微软官方的步骤,以 C++ 为例供参考。

# 设置 Debug

已设置 Debug 的可以跳过。

# 事先准备

  1. 在你的电脑上已经安装了 Visual Studio Code Insiders(为解决 M1 Debug 无法输入的问题直接下载 Insiders 版本)
  2. 在 VS Code 中安装了 C/C++ 插件
  3. 确认电脑已安装 Clang

可以使用如下命令在终端中进行确认:

clang --version

如何提示没有安装,则使用如下命令安装命令行工具:

xcode-select --install

# 创建工作区

创建空文件夹并使用 VS Code 打开,并在 File > Add Folder to Workspace… 将其添加至 Workspace:

螢幕截圖 2021-02-27 21.11.32

创建实例文件 helloworld.cpp 并保存:

#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;
}

Terminal > Configure Default Build Task 中选择 C/C++: clang++ build active file ,这一步操作会在当前目录下的 .vscode 中创建 task.json 文件,并将其中内容替换为:

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "clang++ build active file",
      "command": "/usr/bin/clang++",
      "args": [
        "-std=c++17",
        "-stdlib=libc++",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}"
      ],
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

# 编译程序并 Debug

使用快捷键 ⇧⌘B 或者 **Terminal > Run Build Task ** 进行编译,之后按 F5 进行 Debug(Mac 功能启用则使用 fn + F5)。这一步会在当前目录下的 .vscode 中创建 launch.json 文件,并将其中内容替换为:

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "clang++ - Build and debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": true,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "lldb",
      "preLaunchTask": "clang++ build active file"
    }
  ]
}

之后再进行 Debug 即可。

# 一些问题

微软官方指出,在 macOS Catalina 及更新的系统中,用户可能会在 Debug 输入方面遇到问题。可以通过调整 launch.json 中的 externalConsoletrue ,以弹出终端进行数据的输入。但一部分用户,依然存在问题,一个变通办法就是在 tasks.jsos 中添加如下内容:

{
    "label": "Open Terminal",
    "type": "shell",
    "command": "osascript -e 'tell application \"Terminal\"\ndo script \"echo hello\"\nend tell'",
    "problemMatcher": []
}

微软官方关于这个问题的记录在 GitHub #5079,经过测试 M1 芯片的 VS Code 两种方法都不行。

# LLDB

macOS 中默认使用 LLDB(Low Level Debugger)进行 C/C++ 的调试,具体实现方式不展开。VS Code 上有一个插件 CodeLLDB 可以用于在 VS Code 终端中输入信息,安装插件之后,修改 tasks.json 如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "Build with Clang"
        }
    ]
}

修改 launch.json 如下:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build with Clang",
            "type": "shell",
            "command": "clang++",
            "args": [
                "-std=c++17",
                "-stdlib=libc++",
                "${fileBasenameNoExtension}.cpp",
                "-o",
                "${fileBasenameNoExtension}",
                "--debug"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

M1 Mac 在运行 Debug 之后就会报错,应该是架构不统一导致的,简单介绍下背景:

VS Code:x86/arm64

C/C++ 编译器:我不晓得

CodeLLDB:x86,通过 Rosetta 运行

DebugServer: arm64

# 解决方法

我将罗列几种解决方案,但第一种方案应该就可以满足了:

# 添加 adapterEnv

Debug x86 时使用 Intel 版本的 VS Code Insiders(在下载按钮的下方)并下载 x86 版本的 CodeLLDB 插件,在 VS Code 设置中搜索 adapterEnv ,并添加如下字段:

"LLDB_DEBUGSERVER_PATH": "/Library/Apple/usr/libexec/oah/debugserver"

Debug aarch64 比 x86 会稍微复杂一些,首先需要切换 LLDB,在 VS Code 中搜索 lldb.library 并设置相应的动态库位置。CodeLLDB 也提供了根据文件名搜索对应的库,通过 ⇧⌘P 快捷键输入 Use Alternate Backend... ,可以输入动态库文件名帮助搜索。

这里我提供两个路径:

"lldb.library": "/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/LLDB",
// 或者
"lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB"

上面的两个路径也可以使用通过 ⇧⌘P 快捷键输入 Use Alternate Backend… ,接着再输入 /usr/bin/lldb/Library/Developer/CommandLineTools/usr/bin/lldb 配置。

在配置完 LLDB 路径之后,创建一个 Shell 脚本如下:

arch -arch arm64e /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/debugserver "$@"

并使用 chmod +x <脚本名> 赋予权限,并在 VS Code 设置中搜索 adapterEnv ,并添加如下字段:

"LLDB_DEBUGSERVER_PATH": "<上面脚本的路径>"

# 换用 Xcode

从源头上解决问题。

# 换用 VS Code Exploration

1*GoaJBNfL2xGcfadumGUapg

VS Code 是有三种版本的,VS Code Exploration 比 Insiders 版本还要快,但我没有找到哪里下载,相关信息也很少。

# 参考链接

  1. vscode-lldb/MANUAL.md
  2. VSCode for Apple Silicon based Macs(ARM)
  3. Using Clang in Visual Studio Code
  4. Please support Apple silicon (M1, arm64-darwin)