如何为C代码生成未覆盖的定义使用路径(使用例如gcc)。 我看到这个主题只是学术性的。 (与线路覆盖不同)
答案 0 :(得分:2)
您需要一个工具,可以确定代码中的每个定义,所有可能的用途(例如,计算Def-Use对),将每个Def-Use对与定义的变量以及程序位置(文件,行,列和使用点。
然后对于每个def-use对,你需要在程序中添加检测(“探测”),记录使用该def-use对的时间(通常在使用附近),作为某种特定于该def-use对的布尔变量。 因为有很多这些,所以将各个布尔值组织为布尔数组是有用的。 (显着优化以最小化插入探针的数量:基本块,当执行时,将满足许多def-use对;表示基本块[块覆盖]的执行的布尔值可以作为def-use对的集合.I'我确定还有其他类似的优化。)。
运行程序后,必须转储这些布尔变量,计算实际的def-use信息(例如,包括使用块覆盖数据),然后显示它。
使用源到源程序转换修改程序以执行此操作的标准方案。我的论文 Branch Coverage for Arbitrary Languages Made Easy展示了如何使用我们的DMS软件重组工具包及其重写规则的风格来实现这一目标。本文侧重于分支(块)覆盖,但仪器方面很好。使用的典型转换规则如下所示:
rule mark_if_then_else(condition:expression; tstmt:statement; estmt:statement)=
“if (\condition) \tstmt else \estmt;”
rewrites to
“if (\condition)
{ visited[\new_place\(\tstmt\)]=1;
\tstmt}
else
{ visited[\new_place\(\estmt\)]=1;
\estmt
};”
此规则修改if-then-else构造以为每个有条件执行的块(then和else子句)收集“已访问”布尔值,为每个新块生成新索引。 \ xxxx 表示“语法类型 ssss 的任意代码结构,如果转换规则签名(第一行)声明 ssss:xxxx 。您可以请参阅有关DMS重写规则here的精确语法和含义的更多信息。
事实证明,获取使用信息很难;你需要什么相当于编译器前端,因此OP提到了GCC。 GCC不会进行源到源转换,但是通过使用过程代码修改GCC源来添加探针,您可以获得与gcov基本相同的源到二进制转换的效果。但是,一般而言,GCC不希望帮助您进行此类自定义检测。
我不知道,但我很确定Clang会计算def-use信息。可以使用Clang进行源代码转换,但我没有经验。
我知道我们的DMS does compute def-use information用于C和C ++。这及其进行源到源转换的能力将使构建一个def-use覆盖工具在技术上变得简单明了。 (没有问,但DMS也计算控制流程,因此也可以直接进行路径覆盖。)
然后存在构建显示工具的问题。你需要能够显示def使用对及其状态的东西,可能与代码相关联/叠加在代码上,因此很容易理解每个def和使用。因此,您需要记录有关每个def和使用位置的行和列精确信息。我认为你不能从海湾合作委员会得到这个;它在二进制文件中没有这些信息,但它可能在它构造的AST中有它。您可以从DMS和Clang获取列信息(我认为)。