【远程开发】穿越跳板机和CLion远程开发——全面配置流程

文章目录

  • 穿越跳板机
    • 配置 ProxyJump 方案
      • Cygwin上的配置
    • 建立 SSH Tunneling 方案
  • 代码映射
    • 目录映射方案
      • 配置Rsync加速
    • 远程服务器方案(todo)
  • 远程Debug


tips:本文讲了两种穿越跳板机的方案(推荐ProxyJump方案),和两种代码映射的方案。实际任选一对搭配即可。

穿越跳板机

远程开发有时是在集群中进行,而集群中的机器位于内网环境。为了安全地访问这些内部服务器,通常会设置一个跳板机,这是在网络中的安全性边界处设置的关键访问点,用以增强整体安全性。

“穿越跳板机"就是从外部机器连接到内部服务器(以下简称"目标机"或"远程机”)的过程。

一种简单的做法是:用户先通过ssh连接到跳板机,然后再通过跳板机ssh连接到目标机。然而,这种方式在实际操作时会让人感到繁琐,因此可以通过shell工具提供的"Expect登录脚本"功能来自动化地实现,Xshell、Tabby等shell工具都有这个功能。但是我们的远程开发工具(如jetbrains IDE、vscode)并不支持,可能是它不适用于远程开发,因此要寻找更有效的解决方案。

一般所说的"穿越跳板机"指的是更加高级且无感知的方案,通过隧道技术(Tunnel)来实现,通常有两种做法:

  • ProxyJump(跳板代理):这是ssh工具本身提供的功能,可以通过ssh命令实现,但通常在ssh配置文件(通常为~/.ssh/config)中配置会更为方便。它通过指定一个中间服务器(跳板机),从而通过该服务器访问目标机器。
    使用ProxyCommand(代理命令)也能达到相同的目的。ProxyCommand是ProxyJump的超集,能够设置更复杂/灵活的代理。但仅对于实现跳板代理来说,ProxyJump是更加简单的方式。
  • 建立Tunneling(隧道转发):使用专门的隧道工具。隧道工具可以用于各种网络服务,而不仅仅是SSH。它可以用于创建安全的通信通道,如VPN、端口转发等。然而本文我们搭建的只是 SSH Tunnel,它只能用于SSH,与跳板代理在本质上有相似之处。

下面对这两种方案分别进行详细的介绍。

配置 ProxyJump 方案

跳板代理可以使用命令来指定:

  • ProxyJump的命令格式是:ssh -J <user@jump-host> <user@target-host>
  • ProxyCommand设置跳板代理的命令格式是:ssh -o "ProxyCommand=ssh -W %h:%p <user@jump-host>" <user@target-host>

但每次输入这么长的命令会很繁琐,而且JetbrainsIDE的SSH配置界面并不支持添加命令选项,因此我们采用配置文件的方式来实现。

  • 用户级的配置文件:~/.ssh/config
  • 全局配置文件:在windows上是%PROGRAMDATA%\ssh\ssh_config,在macos/linux上是/etc/ssh/ssh_config
  • 具体的配置格式参见ssh_config文件帮助手册。

一般格式:

# 使用Host关键字创建块结构
# 别名通常是一个便于记忆的名字,配置完成后可以直接通过`ssh 别名`建立连接。
Host <别名># 要登录的真实主机名,也就是平时我们使用ssh后面跟的地址名称,通常是ip地址。HostName <host># 端口号,默认22Port <端口号># 指定登录的用户名User <用户名># 指定私钥文件。默认是~/.ssh/id_rsa或~/.ssh/id_dsa等文件,如果没有合适的密钥则会自动切换到密码身份验证方式。# 在windows上,如果用的是Cygwin的ssh,则可以配置成windows用户目录,否则ssh默认是在cygwin的用户目录中找密钥文件。IdentifyFile <私钥文件>

穿越跳板机的具体配置如下所示:

# 全局配置
Host *# 指定 SSH 客户端接受的远程主机(服务器)提供的主机密钥算法,添加对ssh-rsa的支持。(作为客户端时才有用)# 【为什么要配置HostKeyAlgorithms +ssh-rsa】# openssh8.8以上的版本认为ssh-rsa加密方式不安全, 因此默认不允许这种密钥用于登陆。# 如果使用ssh-rsa密钥会报错:Unable to negotiate with UNKNOWN port 65535: no matching host key type found. Their offer: ssh-rsa,ssh-dss.# 这个错误表明远程 SSH 服务器提供的主机密钥类型(Host Key Type)不被你的 SSH 客户端支持。# 具体来说,错误中提到服务器提供的两种主机密钥类型为 ssh-rsa 和 ssh-dss,而你的 SSH 客户端没有匹配的支持这两种类型的密钥。# Q: 我用的是密码登录,和这个有关系吗?# A: 虽然密码登录通常不涉及主机密钥验证(因为这主要用于密钥登录),但在连接时服务器仍然会提供主机密钥,#    并且客户端会尝试验证。如果服务器的主机密钥算法不在客户端支持的列表中,就会出现这个错误。HostKeyAlgorithms +ssh-rsa# 指定 SSH 服务器接受的用户公钥算法。(作为服务器时才有用,放在这里是为了提醒自己)PubkeyAcceptedKeyTypes +ssh-rsa# 指定密钥文件# IdentityFile <密钥文件># 跳板机配置
Host jump-hostHostName <跳板机ip>User <跳板机用户名>Port <跳板机ssh端口># 远程机配置
Host remote-hostHostName <远程机ip>User <远程机用户名>Port <远程机ssh端口># 指定跳板代理。多个代理可以用逗号分隔,并且将按顺序访问。# ProxyJump jump-host# 也可以使用ProxyCommand来配置跳板代理。ProxyJump和ProxyCommand只需要配置一个。# 需要注意的是,JetBrainsIDE目前还不支持Windows上的ProxyJump。# 也就是说如果使用ProxyJump,你可以通过`ssh remote-host`连接到远程机,但在JetbrainsIDE中会连接失败。# 详见jetbrains issues:https://youtrack.jetbrains.com/issue/IDEA-214679/ProxyJump-not-supportedProxyCommand ssh -W %h:%p jump-host

如果想要使用密钥连接,则把公钥配置到跳板机和远程机各一份即可。

配置好之后,我们可以直接执行ssh 别名代替ssh user@ip建立与服务器的连接

正常来说也可以照旧用ip进行连接,但这里碰到的一个坑是:配置了ProxyJump之后,不能再通过ip访问,必须使用Host别名。当然,如果直接把Host别名配置为ip就可以了。

测试:可以通过ssh命令测试跳板代理是否成功:

> ssh <ssh配置文件中的Host别名>
# 如
> ssh remote-host

输入密码(或使用配置好的ssh密钥)即可成功连接到远程机。


Cygwin上的配置

特别说明一下Cygwin上的配置。如果用的是Cygwin的ssh,则应该编辑cygwin目录下的ssh配置文件(如用户级配置文件是cygwin64安装目录/home/<user>/.ssh/config),而不是windows的。

由于我们可能即会用到windows自带的ssh,也可能会用到cygwin安装的ssh,因此两处的配置文件可能会写的十分相似。
一个令人愉悦的配置方式是,可以使用Include指令来使一个配置文件包含另一个配置文件。因此我们可以这样编写cygwin上的config:

# Include 包含其它配置文件。这里包含windows用户目录的ssh配置文件,就免得在两处编写同样的配置。
Include /cygdrive/c/Users/wushu/.ssh/config# 全局配置
Host *# 指定的密钥文件。如果不设置,则默认是~/.ssh/id_rsa或~/.ssh/id_dsa等文件,如果没有合适的密钥则会自动切换到密码身份验证方式。# 当前用的是Cygwin的ssh,默认会在"cygwin安装目录/home/<user>/.ssh/"中找密钥。这里指定使用windows用户目录中的密钥。IdentityFile /cygdrive/c/Users/wushu/.ssh/id_rsa

特别注意:前面配置文件中的HostKeyAlgorithms +ssh-rsa一定要有,或者写在这个文件里。在撰写本文时,新安装的win11自带的ssh版本是8.6,如果仅仅是这样的话不加并没有关系;但Cygwin安装的ssh版本是9.3,不加一定会报错


建立 SSH Tunneling 方案

我们可以借助MobaXterm工具建立SSH Tunneling(SSH隧道)。
然后只需要ssh连接到本地的tunneling端口,就可以无感地将连接转发到远程机。

具体的配置如下:

  1. 打开MobaXterm,选择tunneling
    在这里插入图片描述

  2. 创建 SSH tunnel
    在这里插入图片描述

  3. 配置并保存
    在这里插入图片描述

  4. 点击启动。(还可以点选自动启动和自动重连)
    在这里插入图片描述

    第一次启动时,会提示信任身份,并要求输入跳板机的ssh密码(如果没有配置密钥)。
    在这里插入图片描述

测试:启动后,可以通过ssh命令测试隧道转发是否成功:

> ssh <远程机用户名>@<本机ip> -p <本机tunnel端口>
# 如
> ssh user@127.0.0.1 -p 12345

此命令将直接连接到远程机,如果没有配置密钥,则显示让输入user@127.0.0.1的密码,实际上就是远程机的ssh密码

> ssh user@127.0.0.1 -p 12345
user@127.0.0.1's password: #输入远程机的密码
Last login: Tue Dec 12 16:42:38 2023 from xxx
Welcome to tlinux 1.2 64bit
Version 1.2 20130106 

代码映射

目前远程代码映射主要有两种方案:

  • 目录映射(传统):用ftp/sftp、webdav等方式建立目录映射,自动或手动地同步改动的文件。
  • 远程服务器(现代):jetbrains 的 gateway 和 vscode 的 remote-ssh 插件 都是这种方式。(其实严格来说这种不算是代码映射,而是远程控制)
    • remote-ssh 会在远程机安装一个vscode-server,本机的remote-ssh插件和远程机的vscode-server建立连接实现远程开发。
    • gateway 会在远程机安装一个对应的IDE后台程序,并在本地启动一个瘦客户端(Jetbrains Client),瘦客户端和远程机的IDE后台建立连接实现远程开发。gateway即可作为一个独立的启动器安装,也默认捆绑在jetbrains的IDE中。

两种方案的优缺点分析:

  • 远程服务器方案
    • 优点:是彻底的远程环境。本地运行瘦客户端可以减少本机的内存占用。
    • 缺点:网络不好可能会出现卡顿,断网时无法进行编码。
  • 目录映射方案
    • 优点:在本地拥有代码文件,因此可以使用本地的工具来访问代码,如使用git图形化工具来管理代码,使用notepad++查看文件的空白符。
    • 缺点:因为有本机和远程两份代码文件,因此可能存在比较麻烦的同步问题:大工程同步要很久,可能需要设置很多排除目录以降低同步时间。配置比较麻烦。
  • 二者各有优劣,我们可以按需选择。

CLion支持这两种方案(见CLion远程开发官方文档),下面进行详细的介绍。

目录映射方案

1. 配置SSH连接
在这里插入图片描述

上图示的Host和端口填写的是 ssh tunnel 方案的。如果你用的是ProxyJump方案则要填写远程机的Host(ssh配置文件中的Host别名)和端口。
在这里插入图片描述

2.1 配置sftp - 连接,使用刚刚配置好的ssh。“设为默认"的目的是用于在第3步"开启自动同步”(自动同步使用默认的Deployment)。Root path通常设置为远程机上的项目根目录。
在这里插入图片描述

2.2 配置sftp - 目录映射
如果刚刚把Root path设置为远程机上的项目根目录,那么这里的"Deployment path"可以直接写"/"。
但如果项目很大,只想映射其中几个目录,可以通过点击Add New Mapping添加多个映射来实现。
在这里插入图片描述

2.3 配置sftp - 排除目录,按需配置即可。
在这里插入图片描述

3. 设置自动同步策略。按需选择。始终自动同步可能会导致IDE卡顿;按下Ctrl+S时同步是一个不错的选择。也可以不自动同步,而是完全手动上传和下载。
在这里插入图片描述

手动上传/下载/同步(查看差异):右击文件视图的文件或目录名,选择Deployment,可以对该文件或目录进行上传/下载/同步。
在这里插入图片描述


配置Rsync加速

在配置SFTP的时候,有一个Rsync选项。使用Rsync可以显著提高同步的速度。

摘自官方文档-windows客户端细节:对于 Windows 上的文件同步,默认情况下,CLion 依靠自己的远程主机访问(Remote Host Access),并使用 tar 工具在主机端进行压缩。这种机制比 macOS 和 Linux 上使用 Rsync 工具同步的速度慢。您可以在部署设置中选择 "使用 Rsync 进行下载/上传/同步 "复选框,在 Windows 上启用 Rsync 同步。
在这里插入图片描述

勾选它,然后配置Rsync

MacOS和Linux自带Rsync,所以几乎不需要再设置什么。前往Rsync的设置界面,点击Test Connection显示"successful"表示成功检测到工具,然后手动上传一个文件测试,一般都会成功上传。

Windows并不自带Rsync,根据CLion的提示,windows上推荐使用cygwin安装rsync和openssh,它们会被安装到cygwin的bin目录下。(首先要下载cygwin,然后用cygwin安装openssh和rsync。此文有讲解rsync的安装,用同样的方式再安装OpenSSH即可)

前往Rsync的设置界面,配置rsync和ssh的全路径,点击Test Connection显示"successful",然后手动上传一个文件来测试,如果成功那么恭喜你。但也可能会报错Unknown message with code "Rsync failed with exit code: 12"
在这里插入图片描述

Rsync options:--no-perms选项用来告诉rsync不要传输任何(文件或目录的)权限信息,否则由于windows和linux的文件权限管理方式不同,上传到linux的文件的权限会发生改变。如果远程目录也由git管理,则可以用git status、git diff <file>清晰的看到文件权限发生了变化。

如果报错,可能是因为安装的ssh版本高于8.8。解决方法是编辑 cygwin64\home\wushu\.ssh\config 文件(如果没有则手动创建),添加以下内容:

Host *# openssh8.8以上的版本认为ssh-rsa加密方式不安全, 因此默认不允许这种密钥用于登陆。# 此行作用是让客户端添加对ssh-rsa的支持。# Q: 我用的是密码登录,和这个有关系吗?# A: 虽然密码登录通常不涉及主机密钥验证(因为这主要用于密钥登录),但在连接时服务器仍然会提供主机密钥,并且客户端会尝试验证。如果服务器的主机密钥算法不在客户端支持的列表中,就会出现这个错误。HostKeyAlgorithms +ssh-rsa

然后再尝试上传/下载,应该就成功了。(本文在前面讲ProxyJump方案的时候,其实就已经在配置文件中添加了这条配置,目的就是应对这个问题)
如果还是失败,那么继续往下看,下面将讲解用于排查真正错误原因的方法。

——————
如何才能排查到真正的错误原因?

很多错误CLion都只会报Unknown message with code "Rsync failed with exit code: 12",通过这个根本无法得知具体是为何失败。因此我们需要手动测试rsync,看到底是哪里出了问题。

进行手动测试前必须要知道的一些事情:(否则这会成为大坑)

  • 我们必须保证自己使用的是用Cygwin安装的openssh和rsync。虽然windows本身也会提供一个ssh,但实际看来并不能用它,我尝试过直接在google上搜索openssh和rsync下载并安装,但实际测试始终不能成功,找不到具体的原因(心态崩)。
    具体测试时出现过的情况我记录在非Cygwin安装的openssh和rsync测试情况记录。
  • Cygwin是什么?
    • Cygwin是一个在Windows上提供模拟Unix/Linux环境的开源软件(就像wsl)。因此它能够安装原生的linux工具,例如我们前面刚安装的openssh和rsync。
    • Cygwin在windows中模拟了Linux文件系统的结构,根目录与Cygwin的安装目录映射。
    • Cygwin提供一个终端工具Cygwin64 Terminal,在这里可以看到完整的linux目录。
    • Cygwin安装的工具只依赖于Cygwin环境,这包括一些环境变量、配置文件等,而不是依赖于Windows。例如,我们安装的ssh并不会读取C:\Users\<username>\.ssh\中的密钥和配置,而是读取cygwin64(安装目录)\home\<username>\.ssh\,因为cygwin64\home\<username>才是cygwin/ssh的用户目录。即便我们不在Cygwin64 Terminal中而是在cmd、powershell等外部终端中使用这些工具也是如此(看来是Cygwin为这些工具做了一些封装)。
  • 早期版本的CLion:启用rsync后,SSH将不能使用"密码"的身份验证方式(会失败),只能使用密钥方式验证。参见相关的Issues:Download from SFTP server using rsync fails with rsync exit code 12 on Windows。目前应该已经解决了,我测试用密码方式验证身份没有问题。

我们可以直接在Cygwin64 Terminal中测试。或者将cygwin64/bin/配置到Windows环境变量,这样就可以用windows上的终端(如cmd、powershell)来测试。就像刚刚说的一样,无论哪种方式,ssh使用的都是Cygwin提供的环境。

配置windows环境变量时注意:一定要配置到Path变量的最前面,目的是覆盖windows提供的ssh。配置好后重新打开cmd输入ssh -V,如果显示OpenSSH_for_Windows_xxx(Windows自带的ssh)则说明没有配置成功。

接下来我们尝试将一个text.cpp同步到远程机。在当前目录下创建一个text.cpp,然后输入以下命令:

# `v`越多日志越详细
$ rsync -avvv -e "ssh -p 12121" ./test.cpp user@127.0.0.1:~/test.cpp # 填写你的远程机用户名和地址(这里是本机tunnel的地址)
opening connection using: ssh -p 12121 -l user 127.0.0.1 rsync --server -vvvlogDtpre.iLsfxCIvu . "~/test.cpp"  (11 args)
Unable to negotiate with 127.0.0.1 port 12121: no matching host key type found. Their offer: ssh-rsa,ssh-dss
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(231) [sender=3.2.7]
[sender] _exit_cleanup(code=12, file=io.c, line=231): about to call exit(12)

可以看到,导致连接失败的错误原因是no matching host key type found. Their offer: ssh-rsa,ssh-dss

这是由于openssh8.8以上的版本认为ssh-rsa加密方式不安全,因此默认不允许这种密钥用于登陆。通过ssh -V看到我的openssh版本是9.3

有同学可能会有疑问:为什么我在CLion的Tools -> SSH Configurations里点击Test Connection显示的是连接成功,这里怎么却失败了呢?

  • 这是因为SSH Configurations里的Test Connection使用的是在环境变量PATH中找到的ssh,默认也就是Windows带的ssh,它的版本低于8.8(我的是8.6),所以直接就能连接成功。
  • 而当我们启用rsync后,rsync用的是我们在Tools -> Rsync界面中配置的ssh,也就是Cygwin的ssh,版本是高于8.8的,因此连接失败,才出现了退出码12的错误。
  • 既然这样,我们自然还会这么想:如果把rsync用的ssh配置成windows自带的ssh不就行了吗?这个问题其实还可以再进一步想:系统明明有ssh,为什么rsync还要我们配置ssh,并且建议都用Cygwin安装的。说实话我也不太清楚,CLion的官方文档中也并没有写。
    猜想的原因可能是:Cygwin安装的ssh和windows的ssh实现并不一样。尽管都是openssh,但Cygwin的ssh应该是linux上的实现,而Windows的ssh则是Windows上的实现。而cygwin安装的rsync的实现也应该是Linux上的实现。rsync的过程需要用到ssh,只有二者都是linux实现,才完全兼容,才能一起正常运行。

因此解决方法就是添加ssh -o HostKeyAlgorithms=+ssh-rsa选项,即:

> rsync -avvv -e "ssh -p 12121 -o HostKeyAlgorithms=ssh-rsa" ./test.cpp user@127.0.0.1:~/test.cpp # 填写你的远程机用户名和地址(这里是本机tunnel的地址)

但每次都输入选项会很麻烦,并且CLion也不支持添加选项。所以最终的方法就是前面说的,编辑 cygwin64/home/<user>/.ssh/config 文件(如果没有则手动创建),添加以下内容。ssh会自动读取此配置。

Host *# openssh8.8以上的版本认为ssh-rsa加密方式不安全, 因此默认不允许这种密钥用于登陆。# 此行作用是让客户端添加对ssh-rsa的支持。# Q: 我用的是密码登录,和这个有关系吗?# A: 虽然密码登录通常不涉及主机密钥验证(因为这主要用于密钥登录),但在连接时服务器仍然会提供主机密钥,并且客户端会尝试验证。如果服务器的主机密钥算法不在客户端支持的列表中,就会出现这个错误。HostKeyAlgorithms +ssh-rsa

然后再执行此命令,应该就可以把test.cpp上传到远程机。如果失败,也会显示具体的错误,那么继续排查即可,只要知道具体的原因,就比较好处理了。

本节到这就可以结束了。

————

非Cygwin安装的openssh和rsync测试情况记录

记录一下测试情况,报的错都比较难排查。其中Connection reset by peer是socket底层的错误,几乎无法排查。

我尝试理解这些错误:rsync需要和ssh配合工作,以及和远程的rsync/ssh进行通信。所以当涉及到不同平台实现的ssh和rsync配合以及通信时,出现不兼容是能够理解的。因此必须使用Cygwin安装的rsync和ssh(这应该都是基于linux实现的),才能和远程linux主机建立正确的关通信。

① 使用 Windows的openssh8.6 和 Cygwin的rsync3.2.7。这是我在手动测试时遇到的第一个问题,因为当时还不了解Cygwin,所以没有将cygwin64\bin配置在环境变量PATH的最前面,导致ssh命令调用的是windows本机的ssh。

> rsync -avvv -e "ssh -p 12121" ./test.cpp user@127.0.0.1:~/test.cpp
opening connection using: ssh -p 12121 -l user 127.0.0.1 rsync --server -vvvlogDtpre.iLsfxCIvu . "~/test.cpp"  (11 args)
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [receiver=3.0.6]
_exit_cleanup(code=12, file=io.c, line=600): about to call exit(12)
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(231) [sender=3.2.7]
[sender] _exit_cleanup(code=12, file=io.c, line=231): about to call exit(12)

这个错误显示了本机和远程机的rsync版本号,因此起初我误以为是版本不兼容。花了老半天时间尝试将服务器的版本更新到与本机一致。非常麻烦,结果最后因为又编译rsync还需要gcc5.x以上(而我的是gcc4.8),我无法把gcc版本升级到5.x以上(怕公司的项目不兼容),就放弃了。

也顺便记录一下rsync的安装:下载对应版本的rsync,然后进行编译安装。(见rsync安装文档)
rsync依赖很多库,因此安装过程可能会比较麻烦。比如autoconf版本低,需要python3但centos6的yum没有python3。

  • centos6安装python3参考此文,但这个文章也是几年前的了,遇到问题请随机应变。安装python3后,再安装pip,然后pip install commonmark
  • 依赖安装完毕后,再回到rsync的解压目录下执行./configure,应该就不报错了。然后再执行makemake install

② 使用 Windows的openssh8.6 和 Google上找的rsync3.0.4;或者使用Cygwin的ssh9.3和Google上找的rsync3.0.4:

> rsync -avvv -e "ssh -p 12121" ./test.cpp user@127.0.0.1:~/test.cpp
opening connection using: ssh -p 12121 -l user 127.0.0.1 rsync --server -vvvlogDtpre.iLs . "~/test.cpp"
Unable to negotiate with 127.0.0.1 port 12121: no matching host key type found. Their offer: ssh-rsa,ssh-dss
rsync: read error: Connection reset by peer (104) # 这是socket抛出的错误
rsync error: error in rsync protocol data stream (code 12) at io.c(791) [sender=3.0.4]
_exit_cleanup(code=12, file=io.c, line=791): about to call exit(12)

③ 使用 Google上找的ssh7.3 和 Google上找的rsync3.0.4:

> rsync -avvv -e "ssh -p 12121" ./test.cpp user00@127.0.0.1:~/test.cpp
opening connection using: ssh -p 12121 -l user00 127.0.0.1 rsync --server -vvvlogDtpre.iLs . "~/test.cpp"
dup() in/out/err failed
rsync: read error: Connection reset by peer (104)
rsync error: error in rsync protocol data stream (code 12) at io.c(791) [sender=3.0.4]
_exit_cleanup(code=12, file=io.c, line=791): about to call exit(12)

远程服务器方案(todo)

因为担心网络问题还没有尝试,实际上这种方案配置起来应该比较简单。
参见CLion官方文档:使用gateway进行远程控制


远程Debug

参考CLion官方文档:远程Debug

CLion提供了两种远程Debug的方案:“远程Debug” 和 “远程GDB服务器”。此二者的区别在官方文档解释的很清楚。在做选择时,主要考虑的是如下两点:

  • "远程GDB服务器"方案要求项目必须是CMake构建的,且Debug服务器只能使用gdb-server。

    什么是"debug服务器":debug工具(gdb)本身也是CS架构的,远程debug需要在远程机器上运行debug-server,再通过本机的debug-client与之连接来实现。

  • "远程Debug"方案适用于任何的构建方式,且Debug服务器可以用gdb-server,也可以用lldb-server。

由于我目前的项目并不是CMake构建的,所以这里选择选用更为通用的"远程Debug"方案。

步骤如下

① 远程机器安装gdb-server,并启动。
(暂时不清楚远程机器上的gdb-server和gdb的版本要不要保持一致或相近,如果碰到问题可以往这方面考虑。我这里安装的gdb-server凑巧和gdb的版本一样,都是7.2-50.el6)

# 安装
yum install gdb-gdbserver # 启动
gdbserver <监听的host>:<监听的port> <executable> # 启动gdbserver,并运行指定的可执行文件
gdbserver <监听的host>:<监听的port> --attach <PID> # 启动gdbserver,并attach到指定PID的进程
# 例。启动gdbserver,并attach到29834进程。监听1234端口,host省略表示允许来自所有host的连接。
gdbserver :1234 --attach 29834

② 先在远程机器上测试一下。 在远程机器上另开一个shell,使用gdb连接到gdbserver,看能否成功。

> gdb <executable> # 此命令启动gdb并加载符号文件
# 在gdb命令行输入此命令,连接到gdbserver
# 格式:target remote <host>:<port>
(gdb) target remote 127.0.0.1:1234

③ 本地机器创建ssh端口转发。(非必须)

由于我的远程机只开放了ssh端口,没有开放其它端口,因此不能直接连接到gdbserver监听的端口。好在ssh提供了端口转发的功能,利用ssh端口就可以间接访问到远程机器上的其它端口。(这里只介绍利用ssh命令和config配置文件进行端口转发的具体操作,用MobaXterm的同学可以自行搜索"MobaXterm如何设置端口转发"。)

方法一:通过ssh命令进行端口转发:

# 建立ssh连接并配置端口转发。将本地1234端口映射到remote-host的1234端口
ssh -L 1234:localhost:1234 <remote-user>@<remote-host> -p <ssh-port>
# 如。这里的remote-host是前面在.ssh/config中配置的远程机host别名
ssh -L 1234:localhost:1234 remote-host # 此命令执行完后,会建立ssh连接和端口转发

方法二:在~/.ssh/config中添加端口转发的配置(如下),然后再执行:ssh remote-host

Host remote-host# (前面的配置这里就不写了)# 端口转发,本地1234端口映射到remote-host的1234端口# 注意,ssh端口转发只有在建立连接后才生效LocalForward 1234 localhost:1234

注意:SSH端口转发依赖于SSH连接,也就是说端口转发需要建立SSH连接后才生效,SSH连接断开后立即失效。因此在进行远程debug的过程中要保持ssh处于连接状态(可以在CLion的Terminal中建立连接,all in IDE)。

④ 测试端口转发是否生效

# (需要下载tcping工具,这个工具下载很简单,不用担心麻烦)
tcping 127.0.0.1 1234

⑤ 配置 CLion 的 Remote Debug configuration

参考官方文档:The Remote Debug configuration

在这里插入图片描述

  • Symbol file:"远程Debug"方案要把符号文件(symbol file)放到本地,目的是让gdb客户端加载到调试信息。通常可执行文件本身就可以很好地用作符号文件,因此直接把远程机器上编译好的可执行文件下载到本机即可(可以利用前面的映射功能同步此文件)。

    低级错误提醒:编译时要使用-g选项才能为可执行文件加入调试信息。这个选项是我们平时调试时必须要加的。

  • Path mappings:配置本地的源码路径和远程机器的源码路径的映射。这样在debug时,程序才能在IDE设置的本地文件断点处停止。

  • Sysroot:动态库的本地根路径。根据官方文档的说法,大多数最新版本的GDB都可以自动下载文件,因此不需要指定此字段。

    稍后启动debug时,在"GDB"选项卡中可以看到自动下载的过程。
    在这里插入图片描述

    也可以手动下载库文件。在GDB命令行中(在远程机器的GDB命令行或者上图的GDB选项卡)执行info sharedlibrary ,可以看到需要哪些动态库。将这些库拷贝到Sysroot路径下,注意目录结构要保持一致:绝对路径相对于Sysroot目录,相对路径相对于本地项目路径(准确说是相对于在GDB选项卡中执行pwd得到的路径)。
    在这里插入图片描述

原神(bushi) Debug !启动!😁
在这里插入图片描述
现在就可以像在本地运行一样检查代码。例如,像平时一样单步执行和检查变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/311713.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive中支持毫秒级别的时间精度

实际上&#xff0c;Hive 在较新的版本中已经支持毫秒级别的时间精度。你可以通过设置 hive.exec.default.serialization.format 和 mapred.output.value.format 属性为 1&#xff0c;启用 Hive 的时间精度为毫秒级。可以使用以下命令进行设置&#xff1a; set hive.exec.defau…

【小沐学Python】Python实现免费天气预报获取(OpenWeatherMap)

文章目录 1、简介1.1 工具简介1.2 费用1.3 注册1.4 申请key 2、接口说明2.1 One Call 3.02.2 Current Weather and Forecasts collection2.2.1 API 调用2.2.2 API 参数 2.3 Historical Weather collection2.4 Weather Maps collection2.5 Other weather APIs 3、接口测试3.1 例…

计算机毕业设计 基于html5的图书管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Armpro脱壳软件搭建教程附源代码

PHP8.0版本&#xff0c;数据库8.0版本 1.配置注册机文件&#xff0c;打开将arm.zip/res目录下&#xff0c;mt管理器搜索将其全部修改为你自己的域名或者是服务器IP 2.然后建立数据库 数据库账号arm 数据库用户名arm 数据库密码EsZfXY4tD3h2NNA4 3.导入数据库 4.配置Redi…

[NCTF 2022]calc

[NCTF 2022]calc 考点&#xff1a;python环境变量注入 打开题目&#xff0c;F12有hint 访问一下得到源码 app.route("/calc",methods[GET]) def calc():ip request.remote_addrnum request.values.get("num")log "echo {0} {1} {2}> ./tmp/log…

从实际工作情况,介绍嵌入式(MCU)软件开发常用(通用)工具

目录 前言 1、代码阅读及编辑工具&#xff08;VSCode、Understand&#xff09; 2、代码对比工具&#xff08;Beyond Compare&#xff09; 3、代码仓库相关工具&#xff08;Git、SVN、Tortoise&#xff09; 4、文本编辑器&#xff08;Notepad&#xff09; 5、电脑文件搜索工…

腾讯云标准型S5服务器2核2G、2核4G和4核8G五年机来了

腾讯云五年特价服务器来了&#xff0c;标准型S5云服务器&#xff0c;可选2核2G、2核4G和4核8G配置&#xff0c;一次性购买五年低至2折&#xff0c;免去续费贵烦恼。腾讯云百科txybk.com分享腾讯云5年服务器特价优惠活动、购买条件、云服务器配置及优惠价格&#xff1a; 腾讯云五…

Python高级用法:生成器(generator)

生成器&#xff08;generator&#xff09; 生成器是一种返回生成序列的方法&#xff0c;与直接使用列表等方式返回序列的方式不同的是&#xff0c;他的生成可以是无限的。 生成器可以与next搭配使用&#xff0c;可以被看作是一种特殊的迭代器。 yield语句 yield一般与循环相…

[NISACTF 2022]babyupload

[NISACTF 2022]babyupload wp 信息搜集 进入页面&#xff1a; 尝试文件上传&#xff0c;但是各种后缀名我都试过了&#xff0c;过不去。 在源码中发现提示&#xff0c;存在 ./source 路径&#xff1a; 访问该路径得到源码&#xff1a; from flask import Flask, request, r…

【Leetcode】1154. 一年中的第几天

文章目录 题目思路代码 题目 1154. 一年中的第几天链接 思路 题目要求是给定一个字符串 date&#xff0c;它代表一个日期&#xff0c;采用标准的 YYYY-MM-DD 格式。需要计算这个日期是当年的第几天。 首先&#xff0c;我们可以通过字符串的索引来提取年、月和日的数值&…

基于YOLOv5+Deepsort 的PCB缺陷检测及计数系统

背景&#xff1a; PCB&#xff08;Printed Circuit Board&#xff0c;印刷电路板&#xff09;是电子产品中至关重要的组成部分&#xff0c;它承载着电子元器件并提供电气连接。在PCB制造过程中&#xff0c;由于工艺、材料或设备等因素的影响&#xff0c;可能会引入各种缺陷&am…

P1019 [NOIP2000 提高组] 单词接龙 刷题笔记

P1019 [NOIP2000 提高组] 单词接龙 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路来自 大佬 Chardo 的个人中心 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 匹配 &#xff1a; 将 第一个字符串末尾 和第二个字符串第一个开始匹配 如果 j<i这段走完了 flag还没…