使用 Delve 调试远程 Go 应用

2023-10-10 01:20

本文主要是介绍使用 Delve 调试远程 Go 应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Delve 是 Go 语言的一个调试器。其目标是为 Go 语言提供一个易用,拥有完整功能的调试工具。

安装可以参考这里。

dlv version 命令验证是否安装成功:

$ dlv version
Delve Debugger
Version: 1.7.1
Build: $Id: 3bde2354aafb5a4043fd59838842c4cd4a8b6f0b $

构建应用

在实际项目中 Delve 可以方便我们在本地调试部署在远程的 Go 应用,但为了使 Delve 的调试器正常工作,一些信息必须在构建过程中避免被编译器或链接器优化。这通过给 go build 添加参数来实现。

构建应用时禁用编译器优化

为了保证进行 debug 时实际运行的代码与源代码相同,需要使用下面的命令构建应用以禁止编译器在编译时对代码进行优化。

go build -gcflags="all=-N -l" -o bin/app

go build 可以用 -gcflags 给 go 编译器传入参数,也就是传给 go tool compile 的参数,因此可以用 go tool compile --help 查看所有可用的参数。"all=-N -l" 表示对所有包的编译应用 -N 和 -l。

执行 go tool compile --help 可以看到 -N 和 -l 的作用:

-N disable optimizations # 禁用优化
-l disable inlining # 禁用内联优化

使用 -m 可以查看编译器优化决策。

Delve 并不强制禁用编译器优化,但这可能会导致实际运行代码与源代码不匹配的情况,那这部分不匹配的代码(如被内联优化的代码)就没法对其进行 debug。而生产环境对性能是敏感的,优化策略不应该被轻易放弃。

确保链接器生成 DWARF 信息

另外,在构建 release 包时我们通常会加上 ldflags 参数:-ldflags '-w -s'。ldflags 给链接器传递参数,-w 将可执行文件体积缩小近 20 %。

go tool link --help 查看 -w 和 -s 作用。

-s disable symbol table # 不使用符号表
-w disable DWARF generation # 不生成 DWARF 信息

需要注意的是,Delve 依赖于 DWARF 信息,因此如果想用 Delve 进行调试,就不能使用 -w 参数。

用 Delve 调试应用

Delve 提供了丰富的本地应用调试能力,此外,Delve 还允许我们从远程连接到其调试器,提供了在本地调试远程应用的能力。

直接运行应用

Delve 有两种方式直接运行应用。一种为在应用根目录(main.go 同级)下直接以 debug 模式启动应用,启动后会进入 Delve 的交互模式。

$ dlv debug
Type 'help' for list of commands.
(dlv) threads
* Thread 457777 at :0
(dlv) 

输入 help 查看所有可用命令,输入 quit 退出并终止程序。

另一种为运行可执行文件:

$ go build -o demo
$ dlv exec demo
Type 'help' for list of commands.
(dlv) threads
* Thread 459012 at :0
(dlv) 

附着到正在运行的 Go 进程上

构建并启动 web 服务。

$ go build
$  ./demo
2021/09/06 15:26:23 read config from: config.yaml
2021/09/06 15:26:23 start server and listen:  127.0.0.1:8081

dlv 附着到 PID 为 17062 的 demo 应用上。

$ psPID TTY           TIME CMD
17062 ttys000    0:00.02 ./thewaytowire
$ dlv attach 17062
Type 'help' for list of commands.
(dlv)

将 Delve 调试器暴露,允许远程连接调试

上述方式都是在本地进行调试,其基本逻辑都是先启动应用,然后启动 Delve 的调试器,然后让调试器 attach 到应用进程上。

为了能够从远程操控 Delve 的调试器,需要将调试器暴露到网络中,指定远程连接的端口,从远程连接到调试器使用的 api 版本,以及其它参数。上述的三种方式:debug, exec, attach 都支持从远程操控,只需为 dlv 命令加上下述参数:

--listen=:2345 --headless=true --api-version=2 --accept-multiclient

最后一步,本地连接运行在远程的 Delve 调试器

Delve 支持多个编辑器,可以参考 这里。

下面为 GoLand 的使用方式。

创建配置。
在这里插入图片描述

连接调试器。
在这里插入图片描述

这篇关于使用 Delve 调试远程 Go 应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/176913

相关文章

Redis持久化机制之RDB与AOF的使用

《Redis持久化机制之RDB与AOF的使用》:本文主要介绍Redis持久化机制之RDB与AOF的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis持久化机制-RDB与AOF一、RDB持久化机制1、RDB简介2、RDB的工作原理3、RDB的优缺点4

使用Python实现实时金价监控并自动提醒功能

《使用Python实现实时金价监控并自动提醒功能》在日常投资中,很多朋友喜欢在一些平台买点黄金,低买高卖赚点小差价,但黄金价格实时波动频繁,总是盯着手机太累了,于是我用Python写了一个实时金价监控... 目录工具能干啥?手把手教你用1、先装好这些"食材"2、代码实现讲解1. 用户输入参数2. 设置无头浏

Spring Boot 常用注解详解与使用最佳实践建议

《SpringBoot常用注解详解与使用最佳实践建议》:本文主要介绍SpringBoot常用注解详解与使用最佳实践建议,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、核心启动注解1. @SpringBootApplication2. @EnableAutoConfi

mysql递归查询语法WITH RECURSIVE的使用

《mysql递归查询语法WITHRECURSIVE的使用》本文主要介绍了mysql递归查询语法WITHRECURSIVE的使用,WITHRECURSIVE用于执行递归查询,特别适合处理层级结构或递归... 目录基本语法结构:关键部分解析:递归查询的工作流程:示例:员工与经理的层级关系解释:示例:树形结构的数

Redis中RedisSearch使用及应用场景

《Redis中RedisSearch使用及应用场景》RedisSearch是一个强大的全文搜索和索引模块,可以为Redis添加高效的搜索功能,下面就来介绍一下RedisSearch使用及应用场景,感兴... 目录1. RedisSearch的基本概念2. RedisSearch的核心功能(1) 创建索引(2

Redis中HyperLogLog的使用小结

《Redis中HyperLogLog的使用小结》Redis的HyperLogLog是一种概率性数据结构,用于统计唯一元素的数量(基数),本文主要介绍了Redis中HyperLogLog的使用小结,感兴... 目录 一、HyperlogLog 是什么?️ 二、使用方法1. 添加数据2. 查询基数China编程3.

Linux系统调试之ltrace工具使用与调试过程

《Linux系统调试之ltrace工具使用与调试过程》:本文主要介绍Linux系统调试之ltrace工具使用与调试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、ltrace 定义与作用二、ltrace 工作原理1. 劫持进程的 PLT/GOT 表2. 重定

POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能

《POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能》ApachePOI是一个流行的Java库,用于处理MicrosoftOffice格式文件,提供丰富API来创建、读取和修改O... 目录前言:Apache POIEasyPoiEasyExcel一、EasyExcel1.1、核心特性

Java 如何创建和使用ExecutorService

《Java如何创建和使用ExecutorService》ExecutorService是Java中用来管理和执行多线程任务的一种高级工具,可以有效地管理线程的生命周期和任务的执行过程,特别是在需要处... 目录一、什么是ExecutorService?二、ExecutorService的核心功能三、如何创建

使用FileChannel实现文件的复制和移动方式

《使用FileChannel实现文件的复制和移动方式》:本文主要介绍使用FileChannel实现文件的复制和移动方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录使用 FileChannel 实现文件复制代码解释使用 FileChannel 实现文件移动代码解释