nilaway

nilaway

编译时捕获Go代码nil指针异常

NilAway是一款静态分析工具,专门用于在编译时检测Go代码中的nil指针异常。它无需额外注释,能够跨包分析nil流,并提供详细错误报告。NilAway以低开销和高精度著称,适合大型Go项目使用。该工具支持独立运行,也可与golangci-lint和Bazel/nogo集成,为开发者提供灵活的使用方式。

NilAwayGo语言静态分析空指针检测编译时检查Github开源项目

NilAway

GoDoc 构建状态 覆盖率状态

[!警告]
NilAway 目前正在积极开发中:可能会出现误报和破坏性更改。 我们非常感谢任何反馈和贡献!

NilAway 是一个静态分析工具,旨在通过在编译时而非运行时捕获空指针异常,帮助开发人员避免在生产环境中出现空指针崩溃。NilAway 类似于标准的nilness 分析器,但它采用了更复杂和强大的静态分析技术来跟踪包内以及跨包的空值流,并报告错误,为用户提供空值流以便更容易调试。

NilAway 具有三个关键特性,使其脱颖而出:

  • 它是全自动的:NilAway 配备了推理引擎,除了标准的 Go 代码外,不需要开发人员提供任何额外信息(如注释)。

  • 速度快:我们设计 NilAway 时考虑了速度和可扩展性,使其适用于大型代码库。在我们的测量中,启用 NilAway 时观察到的构建时间开销不到 5%。我们还在不断应用优化以进一步减少其占用。

  • 它是实用的:它不会阻止代码中所有可能的空指针异常,但它能捕获我们在生产中观察到的大多数潜在空指针异常,使 NilAway 能够在实用性和构建时间开销之间保持良好平衡。

:star2: 有关更详细的技术讨论,请查看我们的 Wiki工程博客 和论文(进行中)。

运行 NilAway

NilAway 使用标准的 go/analysis 实现,使其易于与现有的分析器驱动程序集成(即 golangci-lintnogo作为独立检查器运行)。

[!重要]
默认情况下,NilAway 分析所有 Go 代码,包括标准库和依赖项。这有助于 NilAway 更好地理解依赖项的代码并减少误报。然而,对于有大量依赖项的大型 Go 项目,这也会带来显著的性能成本(对于支持模块化的驱动程序来说只需一次),并增加依赖项中不可操作错误的数量。

我们强烈建议使用 include-pkgs 标志将分析范围缩小到仅限于您的项目代码。这指示 NilAway 跳过分析依赖项(例如第三方库),让您专注于 NilAway 在您的一方代码中报告的潜在空指针异常!

独立检查器

[!重要]
由于 NilAway 进行的分析较为复杂,NilAway 通过 go/analysis 框架的 Fact 机制 缓存其对特定包的发现。因此,强烈建议使用支持模块化分析的驱动程序(即 bazel/nogo 或 golangci-lint,但不是独立检查器,因为它将所有事实存储在内存中)以获得更好的大型项目性能。提供独立检查器更多是为了评估目的,因为它易于上手。

通过运行以下命令从源代码安装二进制文件:

go install go.uber.org/nilaway/cmd/nilaway@latest

然后,运行 linter:

nilaway -include-pkgs="<YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2>" ./...

golangci-lint (>= v1.57.0)

NilAway 在其当前形式下可能会报告误报。这不幸阻碍了它立即合并到 golangci-lint 并作为一个 linter 提供(参见 PR#4045)。因此,您需要将 NilAway 构建为 golangci-lint 的插件,以作为私有 linter 执行。golangci-lint 中有两个插件系统,使用 模块插件系统(自 v1.57.0 版本引入)要容易得多,这是在 golangci-lint 中运行 NilAway 的唯一支持方法。

(1) 如果您还没有在仓库根目录创建 .custom-gcl.yml 文件,请创建它并添加以下内容:

# 这必须是 >= v1.57.0 以支持模块插件系统。 version: v1.57.0 plugins: - module: "go.uber.org/nilaway" import: "go.uber.org/nilaway/cmd/gclplugin" version: latest # 或固定版本以实现可重现构建。

(2) 将 NilAway 添加到 linter 配置文件 .golangci.yaml 中:

linters-settings: custom: nilaway: type: "module" description: 检测 Go 代码中潜在空指针异常的静态分析工具。 settings: # 设置必须是"字符串到字符串的映射"以模拟命令行标志:键是标志名,值是特定标志的值。 include-pkgs: "<YOUR_PACKAGE_PREFIXES>" # NilAway 可以像其他 golangci-lint 分析器一样在配置文件的其他部分中被称为 `nilaway`。

(3) 构建包含 NilAway 的自定义 golangci-lint 二进制文件:

# 注意,用于引导自定义二进制文件的 `golangci-lint` 版本也必须 >= v1.57.0。 $ golangci-lint custom

默认情况下,自定义二进制文件将在 . 目录下构建,名称为 custom-gcl,这可以在 .custom-gcl.yml 文件中进一步自定义(参见 模块插件系统 的说明)。

[!提示]
缓存自定义二进制文件以避免重新构建,节省资源。如果您使用的是 NilAway 的固定版本,可以使用 .custom-gcl.yml 文件的哈希值作为缓存键。如果您使用 latest 作为 NilAway 版本,可以将构建日期附加到缓存键上,以强制在特定时间段后使缓存过期。

(4) 运行自定义二进制文件而不是 golangci-lint

# 参数与 `golangci-lint` 相同。 $ ./custom-gcl run ./...

Bazel/nogo

使用 bazel/nogo 运行需要稍多的努力。首先按照 rules_gogazellenogo 的说明设置您的 Go 项目,使其可以使用 bazel/nogo 构建,不配置或使用默认的 linter 集。然后,

(1) 在您的 tools.go 文件中添加 import _ "go.uber.org/nilaway"(或您用于配置工具依赖的其他文件,参见 Go 模块文档中的 如何跟踪模块的工具依赖?),以避免 go mod tidy 删除 NilAway 作为工具依赖。 (2) 运行以下命令将NilAway作为工具依赖添加到您的项目中:

# 将NilAway作为依赖项获取,并在go.mod文件中获取其传递依赖项。 $ go get go.uber.org/nilaway@latest # 这不应该从go.mod文件中删除NilAway作为依赖项。 $ go mod tidy # 运行gazelle以从go.mod同步依赖项到WORKSPACE文件。 $ bazel run //:gazelle -- update-repos -from_file=go.mod

(3) 将NilAway添加到nogo配置中(通常在顶级BUILD.bazel文件中):

nogo( name = "my_nogo", visibility = ["//visibility:public"], # 必须具有公共可见性 deps = [ +++ "@org_uber_go_nilaway//:go_default_library", ], config = "config.json", )

(4) 运行bazel build以查看NilAway的工作情况(任何nogo错误都会停止bazel构建,您可以使用--keep_going标志要求bazel尽可能多地构建):

$ bazel build --keep_going //...

(5) 查看nogo文档了解如何向nogo驱动程序传递配置JSON,并查看我们的wiki页面了解如何向NilAway传递配置。

代码示例

让我们看几个例子,了解NilAway如何帮助防止空指针引起的panic。

// 示例1: var p *P if someCondition { p = &P{} } print(p.f) // nilness在这里不报错,但NilAway会报错。

在这个例子中,局部变量p只在someCondition为真时被初始化。在访问字段p.f时,如果someCondition为假,可能会发生panic。NilAway能够捕获这个潜在的空指针流,并报告以下错误,显示这个空指针流:

go.uber.org/example.go:12:9: error: 检测到潜在的空指针panic。观察到从源到解引用点的空指针流:
    - go.uber.org/example.go:12:9: 未赋值的变量`p`访问了字段`f`

如果我们用空指针检查(if p != nil)来保护这个解引用,错误就会消失。

NilAway还能捕获跨函数的空指针流。例如,考虑以下代码片段:

// 示例2: func foo() *int { return nil } func bar() { print(*foo()) // nilness在这里不报错,但NilAway会报错。 }

在这个例子中,函数foo返回一个空指针,在bar中直接解引用,导致每次调用bar时都会panic。NilAway能够捕获这个潜在的空指针流,并报告以下错误,描述了跨函数边界的空指针流:

go.uber.org/example.go:23:13: error: 检测到潜在的空指针panic。观察到从源到解引用点的空指针流:
    - go.uber.org/example.go:20:14: 字面量`nil`从`foo()`在位置0返回
    - go.uber.org/example.go:23:13: `foo()`的结果0被解引用

请注意,在上面的例子中,foo不一定要与bar位于同一个包中。NilAway能够跟踪跨包的空指针流。此外,NilAway还处理Go特有的语言结构,如接收器、接口、类型断言、类型switch等。

配置

我们通过go/analysis中的标准标志传递机制公开了一组标志。请查看wiki/Configuration以了解可用的标志以及如何使用不同的linter驱动程序传递它们。

支持

我们遵循与Go项目相同的版本支持政策:我们支持并测试Go的最后两个主要版本。

如果您有任何问题、错误报告和功能请求,请随时在GitHub上提出问题

贡献

我们非常欢迎您为NilAway做出贡献!请注意,一旦您创建拉取请求,您将被要求签署我们的Uber贡献者许可协议

许可证

本项目版权归2023 Uber Technologies, Inc.所有,并根据Apache 2.0许可证授权。

编辑推荐精选

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

下拉加载更多