Go1.17 新特性,优化抛出的错误堆栈

AI 概述
案例优化总结 平时在日常工程中,我们常常会用到异常恐慌(panic)的记录和追踪。最常见的就是,线上 panic 了之后,我们总想从中找到一些蛛丝马迹。 我们很多人是看 panic 是看他的调用堆栈。然后就开始猜,看代码。猜测是不是哪里写的有问题,就想知道 panic 是由什么参数引起的? 因为知道了诱发的...
目录
文章目录隐藏
  1. 案例
  2. 优化
  3. 总结

平时在日常工程中,我们常常会用到异常恐慌(panic)的记录和追踪。最常见的就是,线上 panic 了之后,我们总想从中找到一些蛛丝马迹。

我们很多人是看 panic 是看他的调用堆栈。然后就开始猜,看代码。猜测是不是哪里写的有问题,就想知道 panic 是由什么参数引起的?

因为知道了诱发的参数,排查问题就非常方便了。为此在 Go1.17,官方对这块的调用堆栈信息展示进行了优化,使其可读性更友好。

案例

结合我们平时所使用的 panic 案例。如下:

func main() {
    example(make([]string, 1, 2), "码云笔记", 3)
}

//go:noinline
func example(slice []string, str string, i int) error {
    panic("码云笔记不一样的技术博客")
}

运行结果:

$ go run main.go
panic: 码云笔记不一样的技术博客

goroutine 1 [running]:
main.example(0xc000032758, 0x1, 0x2, 0x1073d11, 0x6, 0x3, 0xc000102058, 0x1013201)
    /Users/eddycjy/go-application/awesomeProject/main.go:9 +0x39
main.main()
    /Users/eddycjy/go-application/awesomeProject/main.go:4 +0x68
exit status 2

我们函数的入参是:[]string、string、int,核心关注到 main.example 方法的调用堆栈信息:

main.example(
    0xc000032758, 
    0x1, 
    0x2, 
    0x1073d11, 
    0x6, 
    0x3, 
    0xc000102058, 
    0x1013201
)

明明只是函数三个参数,却输出了一堆,对应起来非常的不清晰。

其实际对应是:

  • slice:0xc000032758、0x1、0x2。
  • string:0x1073d11、0x6。
  • int:0x3。

这里存在的问题是,看调用堆栈的人,还得必须了解基本数据结构(例如:slice、string、int 等),他才知道每个函数入参他对应拥有几个字段,才能知道其内存布局的结构,有一点麻烦。

并且从程序运行的角度来讲,这么水平平铺的方式,并不直观和准确。因为不同类型他是多个字段组合成结构才能代表一个类型。这不得还要人为估测?

优化

终于,这一块的调用堆栈查看在 Go1.17 做了正式的改善。如下:

$ go1.17 run main.go 
panic: 码云笔记不一样的技术博客

goroutine 1 [running]:
main.example({0x0, 0xc0000001a0, 0xc000034770}, {0x1004319, 0x60}, 0x0)
    /Users/eddycjy/go-application/awesomeProject/main.go:9 +0x27
main.main()
    /Users/eddycjy/go-application/awesomeProject/main.go:4 +0x47
exit status 2

新版本的调用堆栈的信息改变:

main.example(
    {0x0, 0xc0000001a0, 0xc000034770}, 
    {0x1004319, 0x60}, 
    0x0
)

在 Go 语言以前的版本中,调用堆栈中的函数参数被打印成基于内存布局的十六进制值的形式,比较难以读取。

在 Go1.17 后,每个函数的参数都会被单独打印,并且以 “,” 隔开,复合数据类型(例如:结构体、数组、切片等)的参数会用大括号包裹起来,整体更易读。

其实际对应如下:

  • slice:0x0, 0xc0000001a0, 0xc000034770。
  • string:0x1004319, 0x60。
  • int:0x0。

这里也有一块细节要注意,你会发现 Go1.17 的函数参数的数量和以往的版本相比,少了。是因为函数的返回值存在于寄存器中,而不会存储到内存中。

因此函数返回值可能会是不准确的,所以也在新版本中也就不再打印了。

总结

在 Go1.17 的新版本中,调用堆栈的函数参数的可读性得到了进一步的优化和调整,在后续的使用上可能能够带来一定的排错效率的提高。

以上关于Go1.17 新特性,优化抛出的错误堆栈的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Go1.17 新特性,优化抛出的错误堆栈

发表回复