Share via


VS GDB 调试扩展说明

[原文发表地址]Announcing the VS GDB Debugger extension

[原文发表时间]2015/12/18

今年初我写了一个关于如何在Linux系统上调试Visual Studio 上的C++代码的文章,虽然有一点复杂繁琐,但是是可行的。今天我们发布Visual Studio GDB 调试器扩展预览。这将启用调试远程Linux目标包括物联网设备。

为了使用这个扩展,你需要有Visual Studio 2015 community或以上的版本和安装用于安卓的Visual C++工具。这些工具使用了开源MIENngine,它支持Visual Studio调试器去使用GDB和LLDB也使用的机器接口。GDB调试器扩展了那些表面附加项目的属性,使您可以连接到GDB的Visual Studio调试器,用本地或远程的方式,引进一个新的项目类型包括远程Linux目标。

从VS Gallery开始下载GDB调试器扩展并安装它,这篇文章将会详细介绍如何使用这些扩展,从项目创建到F5包括如何为SSH配置您的windows和Linux环境。我将会在下周的一篇文章中讲如何和Raspberry Pi使用它。

项目创建

在你安装完这些扩展后,创建一个新项目,你会发现在Visual C++,Cross Platform下有一个Makefile Project GDB的新模板。

当我们选择上图的选项,并创建一个新的项目就可以得到一个新的空的解决方法与一些支持文件和readme文件。readme文件介绍了一些内容,但更多的是图片。

如果我们快速的浏览项目的属性,你会看到在调试选项卡的下面我们已经添加了远程和本地GDB调试器选项。我们将在下面详细的介绍这些选项。

一旦配置完成,你就可以点击任何你设置的任何断点并按照你的习惯体验正常的VS调试器:监视,查看,设置和移除断点,等等。

配置SSH

本地SSH客户端

首先你需要获得一个本地SSH客户端,你可以根据你的选择去使用SSH客户端,例如Win32端口的OpenSSHPuTTYMinGW或者Cygwin。SSH客户端将用于安全地传输命令从机器接口到一个远程执行GDB。

对于PuTTY,你需要使用plink.exe作为SSH的可执行文件。为了复制文件到你的Linux机器中,你可能需要完整的putty.exe客户端和pscp.exe。你将需要puttygen.exe创建你的私钥用来SSH访问。在Win32 OPenSSH 端口和Putty中,这些工具可以被VS中NMake使用来构建。注意, 基于SSHMinGW/Cygwin,有利于SSH的可执行,但是不能用于在VS中构建,因为我们不知如何在这儿启动。

在Window上创建你的密钥

在这个时候,我们还不能支持有一个密码短语的证书。

要想使用ssh-keygen工具生成Win32 的公/私密钥,如下所示:

ssh-keygen.exe –t rsa –f yourkey.

你的私钥将在上方指定的文件中像yourkey,而公钥将在文件yourkey.pub中。

对于PuTTY,你需要通过运行puttygen和单击生成,来创建一个可用于SSH身份验证证书。

保存好公钥和私钥在随后的步骤中使用。

在Linux机器上添加你的公钥

在Linux机器上,你需要将公钥添加到~/.ssh/authorized_keys文件中。如果它不存在就看看下面说明如何创建。每个公钥应该单独一行。一旦该文件存在,你可以按照下面指示来做。

nano ~/.ssh/authorized_keys

在编辑器中鼠标右键单击新的一行插入复制的公共密钥文本。上面的截图显示我有两个键添加到文件中,点击ctrl-x退出,会有信息提示你保存。

如果该文件不存在,首先按照下面的步骤去做:

mkdir ~/.ssh
touch ~/.ssh/authorized_keys
chmod 0700 ~/.ssh
chmod 0600 ~/.ssh/authorized_keys

使用SSH连接

从SSH客户端连接:

ssh.exe -i privatekey user@host

从PuTTY连接,加载你保存的会话然后去连接数据并设置你的用户名。现在在连接的前提下扩展SSH,并在Auth节点下添加保存的私钥。回到会话页面并将其保存,现在你可以不用密码,只需双击会话名称就能将其打开。

在你第一次连接时,会提示你保存主机作为可信任连接。在其他工具从Visual Studio内部通过确定的认证连接之前,你必须通过SSH客户端这样做。

在Azure Linux VM上的GDB调试

尽管我们对其描述这个与Azure VM,但是原理上是相同的,任何机器设备运行Linux都将会是它的主/本地VM,服务器或设备。我们对远程Linux目标的唯一要求是,在目前你可以安全地通过SSH使用GDB证书连接并且GDB是存在的。如果你需要Azure Linux虚拟机的入门帮助,请到这来。

你大概已经拥有了一些资源,如果你通过右键单击VS项目添加现有项的功能来添加它。如果你想尝试这个的话,你还可以添加一个新项目。对于这个示例,如下图所示,我添加了一个新的main.cpp。

#include <iostream>

using namespace std;

int main()

{

int loops = 10;

for (int i = 0; i < loops; i++) {

cout << "loop number " << i << endl;

}

cout << "All done" << endl;

return 0;

}

这个源代码显然没有吸引力,它仅仅只是在这儿去练习以下步骤。

你将需要获得远程计算机的地址,例如: myServer. Cloudapp.net.你可以在Azure门户上通过选择你的VM并在主页面上复制DNS地址来获得。

在这个例子中,我将使用Putty工具去连接。无论你使用哪个工具你都需要连接到远程目标至少一次。所以在VS脚本连接之前,你可以接受提示去添加它到你信任的主机上。

在项目属性页上和调试器选项卡上将“启动调试器”设置到“远程GDB”上。

在这里我需要设置我的主机名称,用户名称,我的私钥和我想要使用的安全防护。当使用PuTTy工具时,我需要使用Plink作为用于管道命令而不是交互PuTTY终端。现在我可以设置远程工作目录和远程可执行文件。我没有可执行文件的参数并且Gdb可以作为我远程调试器的可执行文件。应用这些改变以至于我们能看到这些build命令时的值。

我们将在PuTTY中使用pscp结合我们从build选项卡中的参数,私有密钥,用户,主机和远程工作目录。当你准备用这种方式复制文件到Linux主机上时,要确保你使用的远程目录已经存在。接下来我们将用远程可执行文件的名称作为命令,并通过plink来传递,指定build的命令行。在这里请注意如果在你的参数值中有空格,你应该通过加括号来避开。我们在build命令行上指定这些Nmake的选项的项目属性。

如果你打开那行进行编辑,你将能够看到参数名称被赋值。

c:\tools\pscp.exe -i $(PrivateKey) "C:\Users\mgoodner\Documents\Visual Studio 2015\Projects\Project1\Project1\main.cpp" $(RemoteUserName)@$(RemoteHostName):$(RemoteWorkingDirectory)/main.cpp
$(SecureShellExecutable) $(RemoteUserName)@$(RemoteHostName) -i $(PrivateKey) "cd $(RemoteWorkingDirectory);g++ -g main.cpp -o $(RemoteExecutable)"

现在我们看到调试器被设置为远程GDB,在循环中设置断点并按下F5.

开始编译生成代码,看着我们所设置的断点。你会得到你所期望的正常功能。例如设置和移除断点,添加监视,等等。如果你是用ssh客户端连接到机器的,你将在目前的远程目标上看到这些文件,并且你可以直接在那儿运行。

如果你击中了一个错误,你的输出窗口有一条“多个远程数据源不支持”的消息。检查是否有空格你的主机名的后面,如果是这样的话就删除它。

本地GDB调试

除了在Linux窗口中你可以GDB调试扩展器,例如还可以使用MinGW。需要注意的是,你可能需要MinGW bin文件夹在你文件路径下。 例如C:\MinGW\bin,这个文件夹给我们提供了GNU编辑器,gcc,g++和我们会在这里描述的gdb调试器。让我们修改上面本地运行的例子的项目属性,将调试器在下拉菜单中从从远程GDB上更改为到本地GDB。

对于其他选项,我们会指定我们源文件的绝对路径,不要习惯性的在选择对话框中使用“.”。我们可以指定我们可执行文件的名称和路径下可用的GDB。

现在告诉VS如何去编译生成。在NMake属性页编辑生成的命令行。点击“Apply”,我们就可以看到从在Debugging页面设置的变量的值。我们将使用g++来建立这个工作,因为它已经是我们全局路径的一部分,我们会将工作目录下的源文件传给它,告诉它发出调试选项并输出我们所指定在工作目录中的可执行文件。

我们现在可以看见调试器被设置为本地GDB,现在你可以按F5.

我们编译链接它,并查看编译时所停留在的断点。

 

更多关于你项目的生成

在调试选项中的项目属性都可以在NMake的命令行中使用。需要注意的是,你可以为远程和本地GDB设置值,并在你的build命令行中使用,即使你只启动了一项或其他。可用的属性有:

主机名:$(RemoteHostName

用户名称:$(RemoteUserName)

私钥:$(PrivateKey)

安全的可执行文件:$(SecureShellExecutable)

远程工作目录:$(RemoteWorkingDirectory)

远程可执行文件名称:$(RemoteExecutable)

远程可执行的参数:$(RemoteExecutableArguments)

远程调试的可执行文件:$(RemoteDebuggerExecutable)

本地工作目录:$(LocalWorkingDirectory)

本地可执行文件:$(LocalExecutable)

本地可执行文件参数:$(LocalExecutableArguments)

本地调试程序可执行文件:$(LocalDebuggerExecutable)

本地调试器服务地址:$(LocalDebuggerServerAddress)

针对Linux目标,源代码必须在一个远程的Linux机器上去生成。通过从build命令行中调用pscp可以将源代码复制到远程的Linux机器上。使用plink你可以帮助你执行远程Linux上所支持的任何命令。

下面的例子是一个远程拷贝文件和build使用PuTTY工具的命令行:

pscp.exe -i $(PrivateKey) source.cpp $(RemoteUserName)@$(RemoteHostName):$(RemoteWorkingDirectory)/source.cpp
plink.exe $(RemoteUserName)@$(RemoteHostName) -i $(PrivateKey) "cd $(RemoteWorkingDirectory);g++ -g source.cpp -o $(RemoteExecutable)"

注意我们不支持从build命令行调用MinGW/Cygwin工具,那是由于我们不知道如何发起这一进程。你可以使用PowerShell工具的OpenSSH端口,包括sftp的实现。

这是个在本地Windows机器上构建的例子(假设g++在全局路径里)。

g++ $(LocalWorkingDirectory)\source.cpp – g –o $(LocalWorkingDirectory)\$(LocalExecutable)

总结

这是我们我们第一个预览版本,我们需要你的反馈,关于什么对你有用,什么对你无用。我们希望听到那些你生成的跨平台应用程序运行在大的Linux服务器上,当然我希望每个人都能用设备连接到Azure IoT。我们希望能定期发布,我们也正在致力于让本地的GDB服务器和片上调试器在更小的目标设备上相互配合。如果你对这个感兴趣的话请通过这个博客联系我们或者你可以在Twitter@robotdad.上联系我。

 

 

--Marc Goodner