二分查找回归¶
本文档描述了如何使用 git bisect
来查找导致某些功能失效的源代码更改 -- 例如,在从 Linux 6.0 升级到 6.1 后,某些功能停止工作。
本文重点介绍该过程的要点。如果您是内核二分查找的新手,最好遵循 如何验证错误和二分查找回归:它从头到尾地描述了所有内容,同时涵盖了多个方面,甚至内核开发人员有时也会忘记。 这包括尽早检测到二分查找会浪费时间的情况,因为没有人会在意结果 -- 例如,因为问题发生在内核将其自身标记为“tainted”之后,发生在已放弃的版本中,已被修复,或者是由您或您的 Linux 发行版执行的 .config 更改引起的。
使用二分查找查找导致内核问题的更改¶
注意:以下过程假定您已为二分查找做好一切准备。 这包括拥有包含适当源代码的 Git 克隆,安装构建和安装内核所需的软件,以及存储在安全位置的 .config 文件(以下示例假定为“~/prepared_kernel_.config”)以用作每个二分查找步骤中的原始基本配置;理想情况下,您还想出了一种完全可靠且直接的方法来重现回归。
准备工作:启动二分查找,并告诉 Git 您认为可以正常工作和已损坏的历史记录点,Git 将其称为“good”和“bad”
git bisect start git bisect good v6.0 git bisect bad v6.1
除了像“v6.0”和“v6.1”这样的 Git 标签之外,您还可以指定提交 ID。
将您准备好的 .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
推荐的可选任务:尝试在最新的代码库之上还原罪魁祸首,并检查这是否修复了您的错误; 如果是这种情况,它将验证二分查找,并使开发人员能够通过还原来解决回归。
要尝试此操作,请更新您的克隆并检出最新的主线。 然后告诉 Git 通过指定其提交 ID 来还原更改
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。