> For the complete documentation index, see [llms.txt](https://freebsd-journal-cn.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://freebsd-journal-cn.bsdcn.org/2025070809-qian-ru-shi/writing-effective-bug-reports.md).

# 撰写有效的 Bug 报告

* 原文：[Writing Effective Bug Reports](https://freebsdfoundation.org/our-work/journal/browser-based-edition/embedded-2/writing-effective-bug-reports/)
* 作者：Tom Jones

![Bug 报告](/files/iWQIej4muDR8qMFNbnxI)

几年前，我们深受敬重的前 FreeBSD 期刊编辑委员会成员 Kristof Provost 写过一篇关于理想 Bug 报告方式的好文章。遗憾的是，Michael W Lucas 总会在年初就用光我们每期讽刺的额度，所以为了避免“讽刺透支”，决定由我改写 Kristof 的原文，以免出现“反讽破产”。

每个系统维护者都有自己偏好的 Bug 报告与改进请求接收方式。由于 Kristof 是 FreeBSD 中 `pf` 开发的核心人物，他正是为期刊撰写这篇文章的理想人选。

在被要求改写原文时，Kristof 的回应是：

**“我无法在完美的基础上再做改进。”**

因此，我来重述 Kristof 的原话，并给你一些入门建议，帮助你更快整理出最重要、最棘手的 Bug。你可以在这里找到他的博文：<https://www.sigsegv.be/blog/2014/Mar#bug_reports>。

## Bug

软件项目常常让人觉得就是由 Bug 堆砌而成；开发者会说一切都是鞋油和胶带粘起来的。造成最大麻烦的问题往往最难捉摸。“深夜，当 12 个并发请求同时打到我们的测地负载均衡器上时……”并不是复杂 Bug 的罕见开头。有时问题的描述甚至是“运行 1000 小时之后……”这种令人头疼的情况。

幸运的是，并非所有 Bug 都如此。FreeBSD 在许多情况下会 panic，对用户而言可能是糟糕的一天，但对开发者而言，panic 消息可能是定位问题的重要线索。和无声的数据损坏相比，我宁愿碰到 panic。

有些 Bug 只是表面问题，比如字段显示不佳，或文档不清晰（是的，我们也认为这算 Bug！）。

无论你的 Bug 是逻辑上的不可能，还是拼写错误，我会给你展示一个框架，帮助你推动修复。

## Bug 生命周期

在介绍如何写好 Bug 报告之前，先说说之后会发生什么，因为这能解释为什么你需要在最初报告时尽可能多提供信息。

在 FreeBSD 中，大多数 Bug 会通过邮件列表或 Bug 跟踪系统（[bugs.freebsd.org](https://bugs.freebsd.org/)）传播。开发者会定期阅读邮件列表，但最能引起关注的方法还是在 Bug 跟踪系统上提交工单。

新创建的 Bug 会被标记为“new”，处于新 Bug 状态。这时它只是被用户提交，还没有通知到具体的项目领域。

Bugmeister 团队会检查新提交，将其从“new”状态重新分配，并尽量设置正确的分类。开发者可以选择订阅某些类别的 Bug。相关的项目邮件列表也会收到新 Bug 的通知。另外，还会定期发送“该组关注的 Bug”摘要邮件。

Bug 可能会被 Bugmeister 或其他 FreeBSD 项目成员分配给某个开发者。

某个开发者可能决定“接手” Bug，成为该问题的负责人。这通常意味着他决定修复这个 Bug 或分析它。

随后可能会有一些往返沟通，开发者会要求更多信息；如果一切顺利，开发者最终会创建代码审查（在 [reviews.freebsd.org](https://reviews.freebsd.org) 上）。代码审查可能会在 Bug 中引用，也可能只是开发者向熟悉该子系统的同行寻求反馈。

如果需要测试以确认 Bug 是否解决，这会被特别指出。

最终，待代码审查与测试完成，修复就会被提交到 FreeBSD；提交消息通常会包含 Bug 的引用，并附加自动更新。有时修复 Bug 需要多个补丁。

修复提交后，你（用户）就能再次无 Bug 使用软件，前提是你运行的是 CURRENT 快照。许多修复会从 CURRENT 合并到 STABLE 分支（称为 MFC）。如果 Bug 被 MFC，修复就会出现在 STABLE 分支，并包含在下一个点版本中。

从报告问题到修复的过程可能很长；有的问题 20 分钟就能解决，有的问题可能需要数月甚至数年。我见过调试超过十年才关闭的 Bug。

解决问题所需的时间，很大程度上取决于你报告的时机。如果你在提交刚落地后就发现 Bug，很可能当天就能修复。其他 Bug 可能更晚才出现，或只出现在某些 FreeBSD 发行版本的环境中。

修复这些 Bug 的速度，主要取决于 Bug 报告的质量和围绕问题的持续讨论。接下来我们看看好的 Bug 报告该包含什么。

## 哪里提交 Bug 报告

FreeBSD 项目鼓励用户通过多种渠道分享使用体验。按优先顺序，新 Bug 或有趣 Bug 的报告渠道如下：

* 在 [reviews.freebsd.org](https://reviews.freebsd.org/) 上提交带有清晰测试的易于应用的变更
* 在 [reviews.freebsd.org](https://reviews.freebsd.org/) 上提交临时修补的解决方案
* 在 [bugs.freebsd.org](https://bugs.freebsd.org/) 上提交新的 Bug
* 直接给开发者发邮件（或其他形式的沟通）
* 在论坛上抱怨并推测原因
* 在 IRC、Matrix、Discord 或其他聊天渠道留言
* **在社交媒体上愤怒发帖，说 FreeBSD 是最差的**

前两种方式假定了较高的技术水平。如果这对你来说太难，也没关系，我们依然欢迎 Bug 报告。

我们不要求每个人都能做高级开发，只希望每位报告者在每一步尽可能提供相关细节。

对于拼写错误，大多数用户可以立即提出修复建议，但修改文档需要使用开发者工具，我们并不要求每个人都做到。如果你能使用这些工具，创建审查比提交新 Bug 更好，因为最终的变更无论如何都需要审查。

更复杂的 Bug 也许能立即解决；有些复杂的 Bug 答案很简单。然而，另一些 Bug 很难诊断，在很长一段时间里，我们只能通过一些看似无关的失败来侧面推断。

如果你有任何质量的修复建议，最重要的是把你的建议公开发布。顺着列表往下找，直到找到合适的位置。

## 如何写好 Bug 报告

### 应包含的信息

好的 Bug 报告应该包含什么，已经有很多资料可供参考；FreeBSD 中软件的广度使得任何单一模板都很难套用。以下是一些经验法则，告诉你应该包含什么：

* 关于你环境的详细信息
* 你期望发生什么
* 实际发生了什么
* 期望与实际的差异
* 这一点并不总是显而易见
* 触发 Bug 的前因后果
* 时间因素有助于开发者调试问题。如果 Bug 在重启后立即出现，或只在运行 5 天后才出现，所需的调试策略是不同的

### 提供哪些资料

系统运行时会生成很多有助于调试的信息，你可能会被要求提供日志，例如：

* `dmesg` 的输出
* panic 消息的完整文本和堆栈跟踪
* 硬件问题时 `pciconf -lv` 的输出
* syslog 输出
* 工具输出和错误信息

提供的资料宁多勿少；如果开发者不得不再来问你一次，可能会耽误至少一周。

### 环境信息

你需要在描述财富 500 强公司的 Anycast 负载均衡配置和只展示单条防火墙规则之间找到平衡。通常，报告中提供的环境信息少于能够提供的；工具与网络配置的组合有助于开发者理解 Bug。

那么，你的环境包括什么？

我们需要知道你使用的 FreeBSD 版本和有多少台主机。Bug 出现在 14 台和 15 台主机之间这一事实，往往比只知道是 14 台更有意义。

我们需要了解自定义和偏离常规的情况；如果你自己编译了 FreeBSD 或使用软件包，都应该说明。这两种方式我们都支持，但如果你运行的不是 release engineering 版本，那就需要考虑这一点。

如果你运行的不是 FreeBSD，而是 pfSense 或 HardenedBSD 这样的下游发行版，需要一并说明。这并不意味着 FreeBSD 开发者不会帮助你，但隐瞒这一点很可能会惹恼某些人。

这一点很重要，因为下游发行版会使用不同的编译标志、软件包构建 FreeBSD，并附带自己的调优。所有这些都可能导致 Bug 在一个平台上存在而在另一个平台上不存在。

我们真正需要的是你的实际环境，而不是理想化的版本或教程中的示例。

### 期望与实际

报告问题的另一个关键部分是描述你期望发生什么。有些软件无法做到你想要的，要么现在做不到（由于功能尚在开发），要么永远做不到（因为这根本不是 Bug！）。

`ls` 不会复制文件或播放视频，但 `pfctl` 应该能够清除规则状态计数器。请告诉我们你期望的输出和效果，以便我们复核你的所有断言。

提供工具的输出，描述你能测量的实际效果，并标出任何问题。

对你来说工具坏了是显而易见的。你提交的是 Bug，但作为分拣问题的开发者，在发现问题所在方面获得额外帮助至关重要。

许多 Bug 在文本报告中不容易看出，性能问题可能难以关联（也难以诊断和修复）。

请非常清楚说明发生了什么和哪里不正确。

### 触发 Bug 的过程

对于许多 Bug，触发 Bug 前的事件很重要。“做了 X 之后无法再做 Y” 是一份优秀的 Bug 报告——它暗示了一条通往开发者黄金（见下文）的道路。

“`ls` 在磁盘满了之后报告错误的文件大小” 能告诉我们很多信息，而 “`ls` 报告错误的文件大小” 则不能。

在 Bug 出现前后查看 `dmesg` 可能会有帮助；内核子系统会在那里报告错误和资源耗尽。在 `dmesg` 中，我们可以看到接口不断上下波动。

## 提供信息的方式

你提供的信息最好是文本形式。如果有错误消息，应该全部包含；有些软件在执行操作时总是会打印错误消息或奇怪的诊断信息。在 Bug 报告中，你应该尽量包含这些信息。

如果你遇到 panic，可能难以从某处复制粘贴文本。这种情况下，用手机拍照是一种可行的策略；但是，你应该尽量在文件大小和图像清晰度之间取得平衡。理想情况下，你应该拍照并尽可能准确抄录文字。

你的图片托管服务将来很可能会消失，但 FreeBSD Bug 跟踪系统中的文本字符串可以保存几十年。

## 优秀 Bug 报告的关键：复现步骤

一份优秀的 Bug 报告会包含上述大部分信息，但还会包含开发者黄金：复现用例。

对于简单问题，这可能只是命令调用；但对于某些问题，你可能需要编写协同工作的 shell 脚本。网络 Bug 的复现用例可能很难编写，但得益于 vnet jail，实际上只需一个 shell 脚本就可以做到（事实上，防火墙测试套件就是这样工作的）。

复现用例的目标是将问题的复现简化到最基本的组件。

## 主动协助

提交 Bug 后，这可能已经足以让开发者感兴趣。如果你能在提交后的 20 分钟内指出回归或新 Bug，很可能立刻引起开发者关注。大多数开发者在提交变更后会关注邮件列表和 src-commits 列表，正是为了捕捉这类报告。

如果你的 Bug 被搁置或过了一段时间才分配给团队，不要慌；这是相当常见的经历。你可以主动联系在相关领域或类似 Ports 上工作的开发者。只要保持礼貌；你在使用志愿者的时间。

开发者接手 Bug 后，可能会问你问题；时间久了，可能会问：“在最新快照上还会出现吗？”

他们可能会请你提供更多信息或测试补丁。某些只出现在特定硬件上的 Bug，如果没人验证，补丁可能会长时间搁置。

有些 Bug 确实很难搞清楚。如果开发者正在和你合作，欢迎提出你认为可能触发 Bug 的理论。有些 Bug 听起来像鬼故事，直到我们找到最终的修复方案。

## 祝你好运！

撰写并提交 Bug 报告是一件耗费精力的事，有时你会觉得自己的努力无人理睬。但 FreeBSD 是一项志愿者项目，开发者根据兴趣分配时间。我们拥有一群优秀的开发者，他们愿意追踪复杂而隐蔽的问题，但他们需要你的帮助与合作，收集足够的信息来复现和测试。

如果你遵循这里的建议，你会更顺利让 Bug 获得关注，并推动它们被修复。

***

**Tom Jones**，FreeBSD 提交者，对保持网络栈高性能充满兴趣。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://freebsd-journal-cn.bsdcn.org/2025070809-qian-ru-shi/writing-effective-bug-reports.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
