首页
/ 使用OneFuzz结合git bisect定位崩溃引入点

使用OneFuzz结合git bisect定位崩溃引入点

2025-07-10 06:01:47作者:廉皓灿Ida

前言

在软件开发过程中,当发现某个崩溃问题时,快速定位是哪个代码提交引入的问题至关重要。本文将介绍如何利用OneFuzz与git bisect的强大组合,通过二分查找高效定位导致崩溃的代码提交。

准备工作

理解基本概念

  1. OneFuzz:微软开源的模糊测试平台,能够自动化执行模糊测试并分析结果
  2. git bisect:Git提供的二分查找工具,用于快速定位引入问题的提交
  3. 回归测试:验证特定输入是否在代码变更后出现问题的测试方法

所需条件

  • 已安装并配置好OneFuzz环境
  • 目标项目的Git仓库
  • 能够重现问题的崩溃输入文件(如crash.txt)

创建测试脚本

我们需要创建一个能够自动化执行以下操作的脚本:

  1. 清理并构建当前提交版本的目标程序
  2. 使用OneFuzz运行回归测试
  3. 根据测试结果返回适当的状态码

示例脚本解析

#!/bin/bash
set -e

PROJECT=sample
TARGET=sample
BUILD=regression-$(git rev-parse HEAD)
POOL=linux

make clean
make 
onefuzz template regression libfuzzer ${PROJECT} ${TARGET} ${BUILD} ${POOL} \
    --check_regression \
    --delete_input_container \
    --reports \
    --crashes $*

关键参数说明

  • --check_regression:确保发现回归问题时CLI返回非零状态码
  • --delete_input_container:测试完成后删除输入容器
  • --reports:不检查现有崩溃报告
  • --crashes $*:检查命令行传入的崩溃文件

验证脚本

在当前版本测试

./test.sh crash.txt

预期结果:脚本应能检测到崩溃并返回非零状态码(通常为1)

在已知良好版本测试

git checkout <已知良好的提交>
./test.sh crash.txt

预期结果:脚本应返回0,表示未检测到回归问题

执行git bisect

初始化bisect

git bisect start HEAD HEAD~8

这将设置搜索范围为当前HEAD到前8个提交

运行bisect

git bisect run ./test.sh ./crash.txt

bisect将自动:

  1. 检出中间提交
  2. 运行测试脚本
  3. 根据结果决定下一步检查哪个提交
  4. 重复直到找到第一个引入问题的提交

结果分析

命令完成后,git会输出类似以下信息:

52b0249dcb5c07a614a2be47c3deccc3a19d29dd is the first bad commit
commit 52b0249dcb5c07a614a2be47c3deccc3a19d29dd
Author: Example <example@contoso.com>
Date:   Thu Mar 18 15:21:16 2021 -0400

    commit 3

 fuzz.c | 1 +
 1 file changed, 1 insertion(+)

这明确指出了引入问题的具体提交及其变更内容。

完成bisect

git bisect reset

这将退出bisect模式,恢复仓库到原始状态。

高级技巧与注意事项

  1. 构建缓存:对于大型项目,可以考虑在脚本中添加构建缓存机制以加速测试
  2. 并行测试:OneFuzz支持并行测试,可以适当配置以提高效率
  3. 测试范围:合理设置bisect的搜索范围可以显著减少测试次数
  4. 环境一致性:确保每次测试的环境一致,避免环境因素干扰结果
  5. 日志分析:OneFuzz生成的详细日志可以帮助分析崩溃原因

总结

通过结合OneFuzz的自动化测试能力和git bisect的高效搜索机制,开发者可以快速准确地定位引入问题的代码提交。这种方法特别适用于:

  • 大型代码库中的问题定位
  • 模糊测试发现的崩溃问题
  • 难以手动重现的间歇性问题

掌握这一技术将显著提升开发者的调试效率,特别是在持续集成环境中。