使用 vscode 调试 golang 短暂进程

简介: 背景使用 vscode 调试 golang 程序相信大家并不陌生,但当我们要调试的程序有以下特点的话,是不是会变得很棘手?要调试的程序并不由我们直接触发要调试的程序是短暂进程(调试中难以捕获进程 id)本文将以 git-hooks(proc-receive)的调试为例介绍一种针对这种场景的调试方案程序编译本文示例代码地址:https://code.aone.alibaba-inc.com/agit

背景

使用 vscode 调试 golang 程序相信大家并不陌生,但当我们要调试的程序有以下特点的话,是不是会变得很棘手?

  • 要调试的程序并不由我们直接触发
  • 要调试的程序是短暂进程(调试中难以捕获进程 id)

本文将以 git-hooks(proc-receive)的调试为例介绍一种针对这种场景的调试方案

程序编译

本文示例代码地址:https://code.aone.alibaba-inc.com/agit/git-hooks-demo

当然我们在编译代码前要记得关闭编译器优化:

go build -gcflags='all=-N -l' -o hooks/proc-receive.bin cmd/proc-receive/*.go

使用 dlv 托管进程的启动

一般来说我们直接使用的是编译出的二进制文件,但在调试场景下,如果能通过某些手段让程序在真正执行前先“等待”我们的调试器去连接,并且在调试器下发一个“开始执行”的指令后才执行代码逻辑,我们就能实现对这类进程的调试。

幸运的是 dlv 工具就为我们提供了这样的能力。如下,我们事先在调试器中设置好断点,然后将 proc-receive 的启动以 dlv headless server 的形式进行包装,那么在该程序被真正唤起之前就会插入一个 dlv 等待调试客户端的连接的启动暂停!

#!/bin/bash

dlv --log --log-dest hooks/dlv.log --listen=:2345 --headless=true --api-version=2 exec hooks/proc-receive.bin

注意,使用 dlv 启动进程时推荐配置 --log 和 --log-dest 参数,否则会干扰到原程序的 stdout 和 stderr,进而影响程序的正常交互

配置 launch.json

如上,我们通过 dlv headless server 的方式启动的程序,vscode 自然需要进行配套的一些设置:

{
	// 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": "attach proc-receive",
			"type": "go",
			"request": "attach",
			"mode": "remote",
			"remotePath": "${workspaceFolder}",
			"port": 2345,
			"host": "127.0.0.1"
		}
	]
}

开始调试

初始化仓库和 proc-receive 配置

# 初始化仓库
git init --bare /tmp/demo.git

# 配置被 proc-receive 截获的引用
cd /tmp/demo.git
# 开始 push-options 支持
git config receive.advertisepushoptions true
# refs/ok will mark command status `ok`
git config --add receive.procreceiverefs refs/ok
# refs/ng will mark command status `ng`
git config --add receive.procreceiverefs refs/ng
# refs/re will mark command status `ok` with a renamed refname
git config --add receive.procreceiverefs refs/re
# refs/ig will ignore the command totally
git config --add receive.procreceiverefs refs/ig

# 配置 git hooks 指向我们工程里的 hooks 目录
mv hooks hooks.backup
ln -sf $PROJECTDIR/hooks

触发 proc-receive

# repo clone
git clone /tmp/demo.git /tmp/demo
cd /tmp/demo

# add some commit
git commit --allow-empty -m "empty commit on `date`"

# push to trigger proc-receive
GIT_TRACE_PACKET=1 git push origin HEAD:refs/ok/01 HEAD:refs/ng/01 HEAD:refs/re/01 HEAD:master

使用 vscode 进行调试

执行 git push 后,push 的流程在需要唤起 proc-receive 进程的时候就会 hang 住,等待 dlv 客户端的连接

此时,使用 vscode 打开代码工程,在程序中添加断点(因为是短暂进程,不提前设断点的话程序一下子就执行完成了),然后切换到调试 tab,选择 `attach proc-receive`,调试就能够正常开始了!

相关文章
|
7月前
|
JavaScript
VSCode 代码调试
VSCode 代码调试
|
NoSQL 小程序 Cloud Native
你是使用什么工具调试 golang 程序的?
你是使用什么工具调试 golang 程序的?
172 0
VSCode调试 添加命令行参数
VSCode调试 添加命令行参数
506 0
|
6月前
|
编译器 C语言 C++
【VS Code】安装配置调试C/C++(一)
【VS Code】安装配置调试C/C++(一)
108 0
|
5月前
|
网络协议 Go C语言
在golang中调试时的指令和使用技巧
【7月更文挑战第4天】 本文介绍 Go调试工具`dlv`常用命令概览及其使用技巧。
131 2
在golang中调试时的指令和使用技巧
|
5月前
|
编译器 Go C语言
通过例子学习在golang中调试程序
【7月更文挑战第4天】Go语言支持使用cgo进行汇编调试,官方文档在golang.org/doc/asm。注意,调试Go运行时可能遇到变量不可用或行号错误,需谨慎使用step命令。
78 1
通过例子学习在golang中调试程序
|
6月前
|
JavaScript 前端开发 C++
vscode编辑器中如何调试nextjs代码
代码可调式的重要性不言而喻。 对于Programer来说,自己编写的程序能够被优雅调试是一件幸福的事情,特别是习惯了后端程序调试的开发者... 在折腾Nextjs项目的日子里,我走了很多弯路才弄明白在vs code中如何优雅的调试代码。
374 1
vscode编辑器中如何调试nextjs代码
|
6月前
|
项目管理 C++
【VS Code】安装配置调试C/C++(二)
【VS Code】安装配置调试C/C++(二)
97 1
|
7月前
|
编译器 开发工具 C语言
vscode安装+配置+使用+调试【保姆级教程】
vscode安装+配置+使用+调试【保姆级教程】
16146 6
|
7月前
|
Go 开发工具
编程笔记 GOLANG基础 004 GOLANG常用命令及VSCODE快捷键
编程笔记 GOLANG基础 004 GOLANG常用命令及VSCODE快捷键
125 2