TLDR /摘要 :有一种方法,给定两个可执行文件(均由C ++编译,带有调试信息,并且来自相同或近似相同的文件)源代码)以仅列出一个相对于另一个功能不同的功能?
背景/动机 :在每次冲刺结束时,我们的工程团队都会以“英雄”的身份移交给质量保证团队作为候选版本。然后,SQA团队花了几个星期的时间测试候选发布者,以确保其正常工作。 (他们已经尽可能多地使测试自动化,但是有些部分不易于自动化,因此费力的手动测试/验证)。不可避免地,它们会在候选版本中遇到一个或多个错误,此时将提交错误报告,工程人员会修复该错误并生成一个新的候选版本。
在这一点上,SQA团队必须做出决定:他们是从头开始重新启动所有测试,还是假定新的发布候选与以前的发布候选相同,除了请求的修复程序外-即程序的其他部分没有引入回归?
首选(“从头开始”)比较安全,但价格昂贵,并且会导致计划延误。第二种选择(“像以前一样继续测试,但使用新版本”)速度更快,但是如果在使用该工具测试过的程序部分中出现了新引入的错误,则用户有可能遇到回归的风险。旧版本。
因此,当SQA向我咨询有关此决定的建议时,我目前在两个构建日期之间进行了“ svn diff”检查,以准确检查两个构建之间的C ++代码更改,并使用该代码来估算进行全面测试。但是,我们的一些SQA人员对我的构建过程的信任程度不如我,因此他们不愿做出这样的假设,即仅仅因为源代码几乎没有变化,也就是说可执行文件几乎没有变化。 (即,他们说“但是如果在我们不知道的构建机器上更改了某些设置会怎样呢?”;我只能呼吁他们对人类的信念,即没人会做这种事情)
因此,为了缓解SQA(和我自己)的担心,如果我可以使用新的发行候选可执行文件并对它进行“比较”(与旧的/经过部分测试的发行候选可执行文件相比),这将非常有用。 ),然后准确查看哪些功能不同,哪些功能保持不变。 (显然,我只能使用binary-diff或MD5校验和来执行此操作,但是这些操作只会告诉我这两个可执行文件是不同的;它们不会告诉我哪些功能是不同的,而这正是我真正想知道的-例如,当我在“关于”框中修正了一个错字之后,可执行文件中的核心业务逻辑功能相对于先前测试的功能就没有改变)
我知道答案可能与操作系统有关;但是我们可以在Linux,MacOS / X和Linux下进行编译,因此欢迎对这三个操作系统的任何见解。
答案 0 :(得分:0)
这个问题的答案似乎是,不,不存在任何此类工具(至少在反恶意软件社区之外)。
因此,为了查看是否可以完成,我编写了一个简单的概念验证executable_diff实用程序,它或多或少地满足了我的期望。它在Linux和MacOS / X上运行,并在调用时通过反汇编程序(在MacOS / X下为“ otool”,在Linux下为“ objdump”)运行两个可执行文件中的每一个,然后扫描反汇编文本以查看文本中的哪些功能。 -segment(或.rodata段中的字符串)在一个可执行文件和另一个可执行文件之间是不同的。
然后它会打印出一个功能列表,该功能与另一个可执行文件中的功能不相同,并且还会写出一个包含实际差异的文件,以防用户希望了解方式功能不同。
实现此程序的主要复杂因素是,当您更改程序中一个功能的大小时,该变化会在程序的其余部分产生波动,因为文本段后面的所有功能地址都将更改也一样因此,该程序还包含过滤误报的逻辑(通过在执行diff之前将程序集中的绝对地址转换回相应的函数名称)
正如对此问题的评论者所指出的那样,差异可执行文件不能替代使用版本控制并跟踪与每个已构建的可执行文件相关联的存储库修订号,因此您可以在源代码级别进行差异。我写这篇文章只是为了看看它是否可以完成,并且是一个学习型练习,可以使我更多地了解如何对源代码所做的更改反映在生成的二进制文件中。可执行文件_diff仅应被认为是一种粗略的启发式方法,因为在某些情况下无疑会产生错误的肯定结果,而在另一些情况下会错误地忽略有意义的更改。