19

go runtime debug 小技巧

 3 years ago
source link: https://studygolang.com/articles/30789
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

来自公众号:新世界杂货铺

前言

本意是打算研究一下go程序的启动流程,然后就去网上搜索了一下入门教程。结果令我有点沮丧,搜到的几乎所有文章开篇都是通过 GDB 调试, 然后就是不同平台下的汇编代码。。。

这令我很不开心, 虽然C/C++应用很广泛, 但是我对它真的没啥兴趣啊, 对它相关的调试工具就更加不感冒了, 虽然它可以调试go程序, 但是总感觉心里少了点什么, 难道 dlv 它不香嘛, 于是就有了今天这篇文章

dlv命令行debug

dlv的名头应该不用我多说, 所以我们直奔主题

  1. 开始debug
dlv debug test.go

执行上述命令后, 就会进入debug交互命令行界面, 在这个界面任何时候输入 h 都会打印帮助信息.

  1. 增加函数断点
# 交互界面输入下面命令后, 会在main包下的main函数打上一个断点
b main.main
  1. 指定行断点
# 在test.go的文件第6行打上一个断点
b test.go:6
  1. 开始执行

zEV3mye.jpg!mobile

如上图所示, 我们继续执行时会发现 => 会停留在我们前面标记的断点处。这里的其他命令我们在本篇文章不做过多的介绍了, 我们尽量紧扣本篇的主题。

  1. 打印调用栈

FbmIZfv.jpg!mobile

如上图所示, 我们通过dlv的调用栈可以看见调用main函数之前,还执行了asm_amd64.s(本次debug的机器为mac)的汇编代码和proc.go的main函数。

意外之喜, 本来只是单纯的不想用GDB调试去了解go程序的启动流程, 现在却也有了一些头绪, 下面我们继续本篇的主题

  1. 在runtime包中标记断点并开始调试

ZzqABbr.jpg!mobile

综上: 按照上面的步骤, 我们通过dlv就可以进行runtiime的调试, 并且还可以了解go程序的启动流程

vscode图形化debug

我个人比较喜欢用vscode进行代码编辑, 所以在撸go的时候用的也是vscode, 体验还是非常不错的

关于vscode如何配置go的开发环境和配置图形化debug就不再本篇过多赘述, 笔者在这里分享一下自己在vscode中关于go的配置

"go.useLanguageServer": true,
"go.languageServerExperimentalFeatures": {
    "format": true,
    "diagnostics": true,
    "documentLink": true
},
"go.languageServerFlags": ["-rpc.trace"],
"go.gotoSymbol.includeGoroot": true,
"go.gotoSymbol.includeImports": true,
"go.useCodeSnippetsOnFunctionSuggestWithoutType": true,
"go.useCodeSnippetsOnFunctionSuggest": true,
"go.autocompleteUnimportedPackages": true,
  1. 打断点

本部分在备用电脑上面完成,go版本为: go1.14.2

YBjiama.jpg!mobile

此次直接复用了前面文章 go中字符串转字节切片的容量 的demo。三个断点分别位于,main/test.go, runtime/proc.go和runtime/string.go.

  1. 运行

vscode通过F5快捷键即可快速开始debug

IFZ3a2R.jpg!mobile

接下来, 你就可以开始快乐的debug之旅啦

debug不出现在call stack的函数

细心的同学肯定已经发现了,在上面vscode图形化debug的调用栈里面并没有runtime/string.go的影子。接下来, 我们结合本篇的主题继续往下分析

相信看过我 切片真的是引用嘛? 这篇文章的同学,心里已经基本有数了。对于这种即没有调用栈也没有明确调用者的函数,我们遵循以下两点即可完成对它的debug

  1. 首先查看其汇编代码
# go代码转汇编
go tool compile -N -l -S test.go

关键汇编代码如下:

7F3YJj.jpg!mobile

如上图所示,我们发现了 stringtoslicebyte 函数, 这样我们就可以打断点了, 只要打上了断点就可以快乐的调试了

  1. runtime函数打断点时机

部分rumtime函数打好断点后, debug程序会无法启动, 这个时候就需要延迟打点(“延迟打点”为笔者自己总结的名字)了。

首先,在main函数的入口处打一个断点(调用runtime函数之前的断点均可),删除runtime函数的断点。

最后, 等待debug程序启动了,再给runtime函数打上断点即可。

至此, 祝各位开启快乐的debug之旅。

注: 写本文时, 笔者所用go版本为: go1.13.4;

原创不易, 卑微求关注收藏二连.

有疑问加站长微信联系

iiUfA3j.png!mobile

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK