最近碰到一个问题,如何在Windows的IDE或者文本编辑器上,远程调试Linux服务器上的golang程序。

虽然想说gdb走你,但既然go有dlv这样的类似Java的jdwp的原生方案,而且我用的Visual Code的官方Go插件支持这种方案,那就试一下这个方案吧。

2019-03-15追加:dlv支持debug、attach和exec三种方式。其中,debug是需要重新编译源代码的,后面两种不需要。也因此debug更适合开发阶段那种“写几个函数,F5一下看看能不能动”的场景,也是Visual Code官方文档记述的远程调试go的唯一方式。这篇文章讲述的是dlv debug这个方式,后续两个方式将在后续发出。

环境

  • 近端
  • Win7 64bit
  • Visual Code 1.32.1 x64
  • Go 1.10
  • 远端
  • OpenSuSE 42.1
  • Go 1.10
  • git 2.12.3
  • 示例项目
  • hello/main.go,内容如下
package main

import "fmt"

var globalVar int

func main() {
globalVar = 2
localVar := 1
globalVar++
localVar++
fmt.Printf("%v + %v = %v\n", globalVar, localVar, globalVar+localVar)
}

准备01. 部署远端dlv

首先远端需要先装好go、git和make的编译全家桶。然后设置好GOPATH,在这里我把/root/go作为这次的GOPATH。

export GOPATH=/root/go

然后从github.com上下载dlv下来,将dlv编译(make)出来后,将编译好的dlv加入可执行文件搜索路径(PATH)中。

git clone https://github.com/go-delve/delve.git $GOPATH/src/github.com/go-delve/delve
cd $GOPATH/src/github.com/go-delve/delve
make install
export PATH=$PATH:$GOPATH/bin

这时候,执行dlv version应该能看到下面的类似信息(版本和Build随版本不同而不一样)。

Delve Debugger
Version: 1.2.0
Build: ac3b1c7a786d681a5aefcdded9888090d69b3832

准备02. 部署近端dlv

近端可以直接用go来安装dlv,也可以使用Visual Code的Go插件来安装,Visual Code都能识别。这里使用的是Go插件的方法。

在Visual Code的菜单栏上,通过View->Command Palette打开Visual Code的命令界面,输入>Go:install/update Tools后回车,就能看到选择安装哪个go工具的菜单。选中dlv后,点击OK按钮,就会自动安装了。安装过程以及提示信息可以在OUTPUT窗口查看。

 
install_dlv_on_VCode

准备03. 添加debug方案

另外,需要给Visual Code添加对应的debug方案(debug configuration)。在Visual Code的菜单栏上,通过Debug->Open Configurations打开launch.json的编辑界面。在configurations数组中,加入以下内容后,保存文件。

{
"name": "Launch remote",
"type": "go",
"request": "launch",
"mode": "remote",
"remotePath": "/root/go/src/hello",
"port": 2345,
"host": "192.168.33.123",
"program": "${fileDirname}",
"env": {}
}

现在,我们就完成了远程调试的所有必须准备了。

执行方法

dlv的debug远程调试需要远端和近端都持有全部的源代码文件。为了方便,这里就不改变GOPATH,在远端直接将整个项目,扔到$GOPATH/src里面,源代码文件路径为$GOPATH/src/hello/main.go;在近端,直接创建hello目录,就把源代码文件直接放在里面。

首先,我们需要先到项目里,启动dlv的服务端。

cd $GOPATH/src/hello
dlv debug --headless --listen ":2345" --log --api-version 2

画面显示以下内容则说明dlv服务端已经就绪。

API server listening at: [::]:2345
INFO[0004] launching process with args: [/root/go/src/hello/debug] layer=debugger

然后,回到Visual Code进入debug界面,选择“Launch remote”方案后,点击启动来进行go debugger,就能启动远程调试。大部分的操作和本地调试无异,堆栈、变量、watch都能正常使用。

 
run_debug_in_VCode.gif

总结

通过Visual Code+dlv来进行go程序的远程调试,对“开发用Windows,生产用Linux”之类的场合下,调试与系统相关的问题非常有帮助。而且,Visual Code的图形界面和代码提示实在是相当方便。

但是debug这个做法有两点不完善的地方。第一个是它原理上需要远端对源代码进行编译,局限了它在除了开发测试环境外的使用场景,也使得每次调试都得等它编译;另一个是因为远端和近端都得有相同的源代码,无论是dlv还是Visual Code的Go插件,目前都没法自动将本地改动过的代码上传到远端去,因此无法实现“F5走你”的一键操作,手工工序太多,使得“debug驱动开发”(笑,虽然不鼓励,但无法消灭啊)的模式难以开展。

所以,最好还是乖乖装个Linux桌面本地调试吧。

参考

delve官方项目
Visual Code的go的debug官方帮助
Visual Code的预定义变量清单

利用delve(dlv)在Visual Code中进行go程序的远程调试-debug方式的更多相关文章

  1. 【转载】Visual Studio中WinForm窗体程序如何切换.NET Framework版本

    在C#语言的WinForm窗体程序中,有时候我们需要切换WinForm窗体程序项目的.NET Framework版本号,例如从.NET Framework 4.5版本切换到.NET Framework ...

  2. 在Visual Studio 中使用git——同步到远程服务器-下(十二)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...

  3. vscode(Visual Studio Code)中安装Debugger for Chrome插件调试页面

    最近换了下编辑器,改用vscode(Visual Studio Code),很喜欢它左边显示的文件路径,轻松新建文件夹和文件,也喜欢它的编码转换功能,gbk和utf-8可以随时切换,因为公司网站有些页 ...

  4. 在Visual Studio 中使用git——同步到远程服务器-上(十一)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...

  5. 在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure

    [题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在 ...

  6. Visual Code中的智能提示

    https://code.visualstudio.com/docs/editor/intellisense C# https://marketplace.visualstudio.com/items ...

  7. 1.2 如何在visual studio 中建立C#程序

    这一节简单介绍一下怎么在visual studio 2015中建立第一个C#程序,我使用的是2015版的visual studio,不同版本可能有一些差异,不过大体上是相同的,这些信息仅供新手参考,大 ...

  8. Visual Studio中设置Nuget程序包源

    用vs2015,默认的程序包源是Microsoft and .NET,很多常见的开源包在里面搜索不到. 这时候就需要配置一个更开放的包源,网上搜了一下,都没人提供这个问题,所以自己动脑花了一番脑经,看 ...

  9. visual studio中使用clrscr程序出错

    clrscr()函数的作用是“清屏”,即把标准输出设备中以前的显示记录清除,包含在头文件#include<conio.h>中,但暂时较旧的编译器中没有这个. 如果想要具有相同作用的函数,可 ...

随机推荐

  1. Linux之top 监视系统任务的工具

    top 监视系统任务的工具: 和ps 相比,top是动态监视系统任务的工具,top 输出的结果是连续的:  top 命令用法及参数: top 调用方法: top 选择参数 参数: -b  以批量模式运 ...

  2. KMP算法详解&&P3375 【模板】KMP字符串匹配题解

    KMP算法详解: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt(雾)提出的. 对于字符串匹配问题(such as 问你在abababb中有多少个 ...

  3. 第八章 watch监听 84 watch-监视路由地址的改变

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  4. HTML5的快捷方式

    ctrl + /  单行注释 ctrl + shift + /   块注释 ctrl + shift + “+”   展开 ctrl + shift + “-”  折叠 ctrl + alt + L  ...

  5. k8s安装flannel报错“node "master" pod cidr not assigned”

    一.在安装flannel网络插件后,发现pod: kube-flannel-ds 一直是CrashLoopBackOff 此报错是因为安装Kubeadm Init的时候,没有增加 --pod-netw ...

  6. router-link to 动态赋值

    路由定义: 动态赋值: <router-link :to="{path:'/old_data_details/params/'+item.id}" > </rou ...

  7. php类知识---魔术方法__toString,__call,__debugInfo

    <?php class mycoach{ public function __construct($name,$age) { $this->name = $name; $this-> ...

  8. 阅读之web应用安全

    一.三种坏人与servlet安全 认证可以防止“假冒者”攻击,授权可以防止“非法升级者”攻击,机密性和数据完整性可以防止“窃听者”攻击. 二.认证与授权 Web容器进行认证与授权的过程: 客户端:浏览 ...

  9. Python3之threading模块

    import threading # Tips:一个ThreadLocal变量虽然是全局变量, # 但每个线程都只能读写自己线程的独立副本,互不干扰. # ThreadLocal解决了参数在一个线程中 ...

  10. Game HDU - 5242 树链思想

    GameHDU - 5242 题目大意:一个游戏有n个场景形成了棵有根树,根节点是1,每个场景都有它的权值.然后一个人可以选择其中K个分支来走,而每个场景的权重只算一遍,问最大的权值和. 一开始想叉了 ...