2

我有一个 C 程序,我想跟踪属于与具体输入相对应的执行路径的所有分支条件。例如,考虑一个简单的程序:

#include <stdio.h>
#include <string.h>
int test(char* a) {
    if (strcmp(a, "123") == 0)
       return 0;

    if (strcmp(a, "123") < 0)
       return -1;
    else 
       return 1;
  }

   int main() {
      char* a;
      return test (a);
  } 

有了a = "1234",程序返回1和对应的路径条件为strcmp(a, "123") > 0。我想收集strcmp,"123"和这个运算符的值 (-1)。有什么方法可以让我这样做吗?我首先考虑使用一些 C 解析器,但似乎并不那么简单。要获取参数的值,我们必须处理指针分析或外部库调用,我不知道如何解决。

4

1 回答 1

1

您无法选择是否需要解析器。你需要它(包括一个完整的预处理器)。你特别不想做的是滚动你自己的解析器;C 比您想象的要复杂得多,然后您必须担心感兴趣的 C 的特定方言。

但是解析器是不够的。您需要一个工具,可以将名称解析为声明,将表达式解析为类型,可以提取流程图,可以进行分析,尤其是功能点分析,最后是可以构建调用图的工具,考虑到所有这些. 这意味着您需要类似编译器的框架来解决问题。

您也许可以弯曲 GCC(很难,它真的想成为一个编译器)或 Clang(想要成为,但旨在允许其他目的)来做到这一点,但他们想要编译单个程序,您需要一些可以处理的东西程序集(因为 C 程序通常是这样构建的)。我们的 DMS Software Reengineering Toolkit 专为支持此类自定义任务而设计,并具有所有必要的机制。(DMS 还支持 C 的特定方言)。

做出框架选择后,沿着感兴趣的流程路径导航的代码可能并不简单。通用建议将是“解析源代码,应用所有上述分析器,然后使用工具提供的 API 遍历数据结构”,显然特别关注遵循控制流路径的 API。所有这些代码都不太可能很好地适合示例。根据您选择的框架,它会有很大差异。我没有密切关注 GCC 或 Clang 的细节,但我认为它们不会为您提供任何简单的方法来写下路径的符号描述(例如,条件表达式的结合)。我可以告诉你,DMS(通过设计)明确支持构建这样的符号公式。

无论您走哪条路,您都将面临学习如何使用这些工具的教育成本。它们很复杂;期望您的学习曲线相对较长。

于 2013-10-28T13:26:56.653 回答