部署、运行和调试 Linux MSBuild 项目

Linux 支持在 Visual Studio 2017 及更高版本中提供。 若要查看这些版本的文档,请将目录上方的“版本”下拉列表设置为“Visual Studio 2017”或“Visual Studio 2019”。

在 Visual Studio 中创建基于 MSBuild 的 Linux C++ 项目,并使用 Linux 连接管理器连接到该项目后,即可运行和调试该项目。 在远程目标上编译、执行和调试代码。

Visual Studio 2019 版本 16.1 及更高版本:可面向不同的 Linux 系统进行调试和生成。 例如,可以在 x64 系统上进行交叉编译,并在定位 IoT 方案时部署到 ARM 设备。 有关详细信息,请参阅本文后面的指定用于生成和调试的不同计算机

与 Linux 项目交互并对其进行调试方法有若干种。

  • 使用 Visual Studio 传统功能(例如断点、监视窗口和悬停在变量上)进行调试。 使用这些方法,可以像平常调试其他项目类型那样进行调试。

  • 从 Linux 控制台窗口中的目标计算机查看输出。 还可以使用控制台将输入发送到目标计算机。

调试 Linux 项目

  1. 在“调试”属性页中选择调试模式

    GDB 用于调试在 Linux 上运行的应用程序。 在远程系统(而非 WSL)上进行调试时,GDB 可以在两种不同的模式下运行,可从项目“调试”属性页中的“调试模式”选项中进行选择

    Visual Studio Linux 控制台应用的“属性页”对话框的屏幕截图,其中显示已选中“配置属性”>“调试”,突出显示了“调试模式”,在该模式中“GBD”已选中且已在下拉列表中突出显示。

    GDB 用于调试在 Linux 上运行的应用程序。 GDB 能以两种不同的模式运行,可从项目“调试”属性页中的“调试模式”选项中进行选择

    Visual Studio 2017 Linux 控制台应用的“属性页”对话框的屏幕截图,其中显示已选中“配置属性”>“调试”,突出显示了“调试模式”,在该模式中“GBD”已选中且已在下拉列表中突出显示。

    • 在 gdbserver 模式下,GDB 在本地运行,连接到在远程系统上的 gdbserver。 若要使用此功能,必须在 Visual Studio 2022 版本 17.6 及更高版本中的调试器路径下或 Visual Studio 2019 版本 16.11 及更早版本中的 GDB 路径下提供 GDB 的本地 Windows 路径。 有关为 CMake 项目提供 GDB 路径的详细信息,请参阅 gdbserver 配置允许的其他选项(16.7 或更高版本)。

    • 在 gdb 模式下,Visual Studio 调试程序在远程系统上驱动 GDB 。 如果 GDB 的本地版本与目标计算机上安装的版本不兼容,则这是更好的选择。 这是 Linux 控制台窗口唯一支持的模式。

      注意

      如果不能在 gdbserver 调试模式中命中断点,请尝试 gdb 模式。 必须先将 gdb 安装在远程目标上。

  2. 使用 Visual Studio 中的标准“调试”工作栏,选择远程目标

    当远程目标可用时,会看到它按名称或 IP 地址列出:

    显示远程目标 ID 地址的屏幕截图。

    如果尚未连接到远程目标,则会看到使用 Linux 连接管理器 连接到远程目标的说明:

    显示远程体系结构 (x64) 的屏幕截图。

  3. 在已知将执行的某些代码的左滚动条槽中单击,设置断点。 设置断点的代码行上出现一个红点。

  4. 按 F5(或者“调试”“开始调试”)开始调试。

    开始调试时,应用程序先在远程目标上编译,再启动。 任何编译错误都会显示在 “错误列表 ”窗口中。

    如果没有错误,应用将启动,调试器会在断点处暂停:

    显示应用已命中断点的屏幕截图。

    现在,可通过按命令键(如 F10 或 F11),与处于当前状态的应用程序交互、查看变量以及逐行执行代码

  5. 如果需要使用 Linux 控制台与应用进行交互,请选择“调试”>“Linux 控制台”。

    显示 Linux 控制台菜单项的屏幕截图。

    此控制台显示目标计算机的控制台输出,并获取输入并将其发送到目标计算机。

    显示 Linux 控制台窗口的屏幕截图。

配置其他调试选项(MSBuild 项目)

  • 可以使用项目“调试”属性页中的“程序参数”项将命令行参数传递给可执行文件

  • 可以通过在项目的“调试”属性页中使用“预启动命令”来导出 DISPLAY 环境变量。 例如:export DISPLAY=:0.0

    显示“属性页”对话框中的“程序参数”属性的屏幕截图。

  • 可使用“其他调试程序命令”条目将特定调试程序选项传递到 GDB。 例如,你可能需要忽略 SIGILL(非法指令)信号。 可以使用 handle 命令将以下内容添加到上面所示的其他调试器命令条目来实现此目的: handle SIGILL nostop noprint

  • 使用项目的“调试”属性页中的GDB 路径项来指定 Visual Studio 使用的 GDB 的路径。 Visual Studio 2019 版本 16.9 及更高版本中提供了此属性。

使用“附加到进程”进行调试

Visual Studio 项目的调试属性页和 CMake 项目的 Launch.vs.json 设置具有允许附加到正在运行的进程的设置 。 如果需要除了这些设置中提供的控制外的其他控制,则可以将名为 Microsoft.MIEngine.Options.xml 的文件置于解决方案或工作区的根路径中。 下面是一个简单示例:

<?xml version="1.0" encoding="utf-8"?>
<SupplementalLaunchOptions>
    <AttachOptions>
      <AttachOptionsForConnection AdditionalSOLibSearchPath="/home/user/solibs">
        <ServerOptions MIDebuggerPath="C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\Common7\IDE\VC\Linux\bin\gdb\7.9\x86_64-linux-gnu-gdb.exe"
ExePath="C:\temp\ConsoleApplication17\ConsoleApplication17\bin\x64\Debug\ConsoleApplication17.out"/>
        <SetupCommands>
          <Command IgnoreFailures="true">-enable-pretty-printing</Command>
        </SetupCommands>
      </AttachOptionsForConnection>
    </AttachOptions>
</SupplementalLaunchOptions>

AttachOptionsForConnection 具有你可能需要的大多数属性 。 上面的示例演示如何指定要搜索更多 .so 库的位置。 子元素 ServerOptions 允许改为使用 gdbserver 附加到远程进程 。 若要执行此操作,需要指定本地 gdb 客户端(Visual Studio 2017 中附带的客户端如上所示)和带符号的二进制文件的本地副本。 SetupCommands 元素允许将命令直接传递给 gdb 。 可以在 GitHub 上找到 LaunchOptions.xsd 架构中提供的所有选项。

指定用于在基于 MSBuild 的 Linux 项目中生成和调试的不同计算机

可将远程生成计算机与远程调试计算机分开,以便处理基于 MSBuild 的 Linux 项目和面向远程 Linux 计算机的 CMake 项目。 例如,现在可以在 x64 系统上进行交叉编译,并在定位 IoT 方案时部署到 ARM 设备。

默认情况下,远程调试计算机与远程生成计算机相同(“配置属性”“常规”>“远程生成计算机”)。 若要指定新的远程调试计算机,请在 解决方案资源管理器 中右键单击项目,然后转到 “配置属性>调试>远程调试计算机

显示“属性页”对话框中的 Linux 远程调试计算机属性的屏幕截图。其中显示了用户名、身份验证类型和端口。

“远程调试计算机”的下拉菜单中填充了所有已建立的远程连接

若要添加新的远程连接,请导航到“工具”“选项”>“跨平台”“连接管理器”,或者在“快速启动”中搜索“连接管理器” 。 另外,还可以在项目的“属性页”(“配置属性”“常规”>“远程部署目录”)中指定新的远程部署目录。

默认情况下,仅将进程调试所需的文件部署到远程调试计算机。 可以使用 解决方案资源管理器 来配置将哪些源文件部署到远程调试计算机。 单击源文件时,可在解决方案资源管理器下方看到其文件属性的预览:

显示 main.cpp 文件属性的屏幕截图,其中突出显示属性 content = False。

“内容”属性指定是否将文件部署到远程调试计算机。 可以导航到“属性页”“配置管理器”并取消选中“部署”以获取所需配置,通过这种方式完全禁用部署 。

在某些情况下,可能需要对项目的部署进行更多控制。 例如,你要部署的某些文件可能超出解决方案的范围,或者你需要为每个文件或目录自定义远程部署目录。 在这些情况下,将以下代码块附加到 .vcxproj 文件,并将“example.cpp”替换为实际文件名:

<ItemGroup>
   <RemoteDeploy Include="__example.cpp">
<!-- This is the source Linux machine, can be empty if DeploymentType is LocalRemote -->
      <SourceMachine>$(RemoteTarget)</SourceMachine>
      <TargetMachine>$(RemoteDebuggingTarget)</TargetMachine>
      <SourcePath>~/example.cpp</SourcePath>
      <TargetPath>~/example.cpp</TargetPath>
<!-- DeploymentType can be LocalRemote, in which case SourceMachine will be empty and SourcePath is a local file on Windows -->
      <DeploymentType>RemoteRemote</DeploymentType>
<!-- Indicates whether the deployment contains executables -->
      <Executable>true</Executable>
   </RemoteDeploy>
</ItemGroup>

CMake 项目

对于面向远程 Linux 计算机的 CMake 项目,可以在 launch.vs.json 中指定新的远程调试计算机。 默认情况下,"remoteMachineName" 的值与 "remoteMachineName" 中与远程生成计算机对应的 CMakeSettings.json 属性同步。 这些属性不再需要匹配,"remoteMachineName"中的launch.vs.json值决定用于部署和调试的远程计算机。

CMake 远程调试 launch_schema.json 文件中指定的计算机。远程计算机名称为 ${debugInfo . remoteMachineName}

IntelliSense 建议列出所有已建立的远程连接。 可以导航到“工具”“选项”>“跨平台”“连接管理器”,或者在“快速启动”中搜索“连接管理器”,以便添加新的远程连接 。

如果要完全控制部署,可以将以下代码块附加到 launch.vs.json 文件。 请务必将占位符值替换为实际值:

"disableDeploy": false,
"deployDirectory": "~\foo",
"deploy" : [
   {
      "sourceMachine": "127.0.0.1 (username=example1, port=22, authentication=Password)",
      "targetMachine": "192.0.0.1 (username=example2, port=22, authentication=Password)",
      "sourcePath": "~/example.cpp",
      "targetPath": "~/example.cpp",
      "executable": "false"
   }
]

后续步骤

另请参阅

C++ 调试属性 (Linux C++)