乐趣区

关于php:Go117-新特性优化抛出的错误堆栈

微信搜寻【脑子进煎鱼了】关注这一只爆肝煎鱼。本文 GitHub github.com/eddycjy/blog 已收录,有我的系列文章、材料和开源 Go 图书。

大家好,我是煎鱼。

平时在日常工程中,咱们经常会用到异样恐慌(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 的新版本中,调用堆栈的函数参数的可读性失去了进一步的优化和调整,在后续的应用上可能可能带来肯定的排错效率的进步。

你平时在借助调用堆栈排查问题呢,心愿还取得什么辅助呢?

若有任何疑难欢送评论区反馈和交换,最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,回复【000】有我筹备的一线大厂面试算法题解和材料;本文 GitHub github.com/eddycjy/blog 已收录,欢送 Star 催更。

参考

  • GoTip: New Stack Trace Output Wrong
  • cmd/compile: bad traceback arguments
  • Go 1.17 新个性详解:应用基于寄存器的调用常规
  • doc/go1.17: reword “results” in stack trace printing
退出移动版