二分查找回归¶
本文档描述了如何使用 git bisect
查找破坏某些内容的源代码更改——例如,在从 Linux 6.0 升级到 6.1 后,某些功能停止工作时。
文本侧重于该过程的要点。如果您是二分查找内核的新手,最好遵循 如何验证错误和二分查找回归:它从头到尾描述了所有内容,同时涵盖了即使是内核开发人员有时也会忘记的多个方面。这包括尽早检测到二分查找会浪费时间的情况,因为没有人会关心结果——例如,因为问题发生在内核将自己标记为“受污染”之后,发生在已放弃的版本中,已被修复,或由您或您的 Linux 发行版执行的 .config 更改引起。
使用二分法查找导致内核问题的更改¶
注意:以下过程假设您为二分查找准备好了一切。这包括拥有一个包含适当源代码的 Git 克隆,安装构建和安装内核所需的软件,以及存储在安全位置的 .config 文件(以下示例假设为“~/prepared_kernel_.config”),以便在每个二分查找步骤中用作原始基础;理想情况下,您还找到了一种完全可靠且直接的方法来重现回归。
准备:开始二分查找,并告知 Git 您认为工作和中断的历史点,Git 称之为“good”和“bad”
git bisect start git bisect good v6.0 git bisect bad v6.1
您也可以指定提交 ID,而不是像“v6.0”和“v6.1”这样的 Git 标签。
将您准备好的 .config 复制到构建目录,并根据 Git 检出进行测试的代码库的需求进行调整
cp ~/prepared_kernel_.config .config make olddefconfig
现在构建、安装和引导内核。这可能会由于不相关的原因而失败,例如,当二分查找的当前阶段发生编译错误时,稍后的更改会解决该错误。在这种情况下,运行
git bisect skip
并返回到步骤 1。检查您刚刚构建的内核中回归的功能是否正常工作。
如果它正常工作,则执行
git bisect good
如果它已损坏,则运行
git bisect bad
请注意,即使一次出错也会使其余的二分查找完全偏离方向。为了防止以后不得不重新开始,因此您需要确保您告诉 Git 的内容是正确的;因此,如果您的重现器不可靠,通常明智的做法是多花几分钟进行测试。
发出这两个命令中的一个后,Git 通常会检出另一个二分查找点,并打印类似“Bisecting: 675 revisions left to test after this (roughly 10 steps)”的内容。在这种情况下,返回到步骤 1。
如果 Git 而是打印类似“cafecaca0c0dacafecaca0c0dacafecaca0c0da is the first bad commit”的内容,则您已完成二分查找。在这种情况下,请移至下面的下一个点。请注意,在显示该行之后,Git 将显示有关罪魁祸首的一些详细信息,包括其补丁描述;这很容易填满您的终端,因此您可能需要向上滚动才能看到提及罪魁祸首的提交 ID 的消息。
如果您错过了 Git 的输出,您可以始终运行
git bisect log
以打印状态:它将显示还剩多少步骤或提及二分查找的结果。
建议的补充任务:将二分查找日志和当前的 .config 文件放在一边以供错误报告使用;此外,告诉 Git 将源代码重置为二分查找之前的状态
git bisect log > ~/bisection-log cp .config ~/bisection-config-culprit git bisect reset
建议的可选任务:尝试在最新代码库之上恢复罪魁祸首,并检查是否修复了您的错误;如果是这样,它会验证二分查找,并使开发人员能够通过恢复来解决回归。
要尝试此操作,请更新您的克隆并检出最新的主线。然后通过指定其提交 ID 来告诉 Git 恢复更改
git revert --no-edit cafec0cacaca0
Git 可能会拒绝此操作,例如,当二分查找落在合并提交上时。在这种情况下,放弃尝试。如果 Git 无法自行恢复罪魁祸首,因为稍后的更改依赖于它,则执行相同的操作——除非您二分查找的是稳定或长期内核系列,在这种情况下,您需要检出其最新的代码库并尝试在那里恢复。
如果恢复成功,请构建并测试另一个内核,以检查恢复是否解决了您的回归。
这样,该过程就完成了。现在,按照 报告问题 中的描述报告回归。
二分查找 linux-next¶
如果您遇到仅在 linux-next 中发生的问题,请在 linux-next 分支 “stable” 和 “master” 之间进行二分查找。以下命令将为添加为名为“next”的远程的 linux-next 树启动该过程
git bisect start
git bisect good next/stable
git bisect bad next/master
“stable”分支指的是当前 linux-next 版本(在“master”分支中找到)所基于的 linux-mainline 的状态——因此,前者应该没有在 -next 中显示但在 Linus 的树中没有显示的任何问题。
这将在广泛的更改范围内进行二分查找,其中一些您可能在早期的 linux-next 版本中使用过,但没有问题。可悲的是,没有简单的方法可以避免检查它们:从一个 linux-next 版本到稍后的版本(例如在“next-20241020”和“next-20241021”之间)进行二分查找是不可能的,因为它们没有共同的历史。
其他阅读材料¶
“git bisect” 的手册页 和 Git 文档中 使用“git bisect”对抗回归。
来自内核开发人员 Nathan Chancellor 的 使用 git bisect。