go runtime debug 小技巧

新世界杂货铺 · · 982 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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

前言

本意是打算研究一下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. 开始执行

image

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

  1. 打印调用栈

image

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

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

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

image

综上: 按照上面的步骤, 我们通过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

image

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

  1. 运行

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

image

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

debug不出现在call stack的函数

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

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

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

关键汇编代码如下:

image

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

  1. runtime函数打断点时机

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

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

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

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

注: 写本文时, 笔者所用go版本为: go1.13.4;
生命不息, 探索不止, 后续将持续更新有关于go的技术探索

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


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:新世界杂货铺

查看原文:go runtime debug 小技巧

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

982 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传