Uber Go 出了个静态分析工具 NilAway,还挺实用!

大家好,我是煎鱼。

风水轮流转,Go 程序写多了。总是会这有点问题,那有点问题。问题积累久了就容易出点事件,甚至是事故。

这种时候大家往往会想着引入一些静态分析工具来解决这个问题。

NilAway 分析工具

最近 Uber 开发和开源了一个挺不错的静态分析工具 NilAway:

使用场景是:在 Go 程序编译时就能捕获 nil,达到帮助开发人员规避在生产中出现 nil panic 的问题。

官方认为其具备以下三个重要的特点,让其脱颖而出:

  1. 完全自动化:该分析工具只需要用户提供标准的 Go 代码就可以使用了。不需要其他任何额外的信息。
  2. 速度快:在设计上,NilAway 保持速度快且可扩展,目标是大型代码库也可以使用。在官方的性能测量中,启用 NilAway 时构建时间开销不到 5%。
  3. 很实用:它不能防止代码中所有可能的 nil panic,但能捕获我们在生产中观察到的大部分潜在 nil panic,从而使 NilAway 在实用性和构建时间开销之间保持良好的平衡。

安装

我们只需要在命令行执行如下命令安装:

shell 复制代码
$ go install go.uber.org/nilaway/cmd/nilaway@latest

nilaway 能够遍历扫描目录下的所有文件:

shell 复制代码
$ nilaway ./...

也可以扫描单独的文件:

go 复制代码
$ nilaway demo.go

注:本文安装 @latest 的原因,是因为写此文时 nilaway 还在积极开发阶段,暂时没有发布正式的版本。如果后续有正式版本,也可以指定相应版本号。

代码示例

案例一

看看如下的代码,是在什么场景下有问题:

go 复制代码
var p *P
if someCondition {
      p = &P{}
}
print(p.f) // nilness reports NO error here, but NilAway does.

在上述代码中,当 someCondition 变量值为 true 时,才会初始化结构体 P。如果 someCondition 变量为 false 时,就会出现空指针调用的 panic 问题。

NilAway 工具可以捕获这种错误并报告,会报告如下错误:

go 复制代码
go.uber.org/example.go:12:9: error: Potential nil panic detected. Observed nil flow from source to dereference point:
    -> go.uber.org/example.go:12:9: unassigned variable `p` accessed field `f`

如果我们增加 if p != nil 来做防御,报告的错误就会消失。

案例二

看看如下的代码,是为什么有问题:

go 复制代码
func foo() *int {
	return nil
}
func bar() {
	print(*foo())
}

func main() {
	// 煎鱼正在干点什么...
	bar() // nilness reports NO error here, but NilAway does.
}

函数 foo 返回了一个 nil 指针,该指针在函数 bar 中被直接解引用,导致每当调用函数 bar 时都会出现 panic 问题。

NilAway 工具也能捕获这类跨函数的的问题,会报告如下错误:

go 复制代码
➜  ~ nilaway demo.go 
/Users/eddycjy/demo.go:7:9: error: Potential nil panic detected. Observed nil flow from source to dereference point: 
	-> eddycjy/demo.go:4:9: literal `nil` returned from `foo()` in position 0
	-> eddycjy/demo.go:7:9: result 0 of `foo()` dereferenced

上面的例子虽然是同 package 内跨函数的问题识别,但实际上该工具也嫩能够分析跨 package 的调用。

总结

今天针对 Go 里最常见的 nil 指针问题进行了静态分析工具 NilAway 的分享。虽然目前该工具还没有正式的生产可用。

可以明确的是这是大家在 Go 应用上常碰到的场景,可以多加关注后续的更新。另外 NilAway 是基于 go/analysis 标准开发的,后续可以接入 golangci-lint 等相关工具。大家可以继续保持关注!

文章持续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub github.com/eddycjy/blo... 已收录,学习 Go 语言可以看 Go 学习地图和路线,欢迎 Star 催更。

推荐阅读

相关推荐
煎鱼eddycjy1 天前
新提案:由迭代器启发的 Go 错误函数处理
go
煎鱼eddycjy1 天前
Go 语言十五周年!权力交接、回顾与展望
go
不爱说话郭德纲2 天前
聚焦 Go 语言框架,探索创新实践过程
go·编程语言
0x派大星3 天前
【Golang】——Gin 框架中的 API 请求处理与 JSON 数据绑定
开发语言·后端·golang·go·json·gin
IT书架3 天前
golang高频面试真题
面试·go
郝同学的测开笔记3 天前
云原生探索系列(十四):Go 语言panic、defer以及recover函数
后端·云原生·go
秋落风声4 天前
【滑动窗口入门篇】
java·算法·leetcode·go·哈希表
0x派大星6 天前
【Golang】——Gin 框架中的模板渲染详解
开发语言·后端·golang·go·gin
0x派大星6 天前
【Golang】——Gin 框架中的表单处理与数据绑定
开发语言·后端·golang·go·gin
三里清风_7 天前
如何使用Casbin设计后台权限管理系统
golang·go·casbin