【问题标题】:Which tool can list writing access to a specific variable in C?哪个工具可以列出对 C 中特定变量的写访问权限?
【发布时间】:2012-11-14 05:52:14
【问题描述】:

不幸的是,我什至不确定如何调用这种静态分析。这不是真正的控制流分析,因为我不是在寻找函数调用,也不需要数据流分析,因为我不关心实际值。

我只需要一个工具来列出对特定变量进行写访问的位置(文件、函数)。我什至不在乎该列表是否包含无法访问的行。我可以想象编写一个简单的解析器就足以完成这项任务,但我确信肯定有一个工具可以进行这种简单的分析。

作为一个穷学生,我会很感激免费或更好的开源工具,如果有人能告诉我这种静态分析实际上是如何调用的,我将同样感激!

编辑:我忘了提到代码库中没有指针算法。

【问题讨论】:

  • 在运行时,您可以调试并在变量地址处放置内存断点,但我知道这不是您要问的。
  • 你不能只要求编译器生成一个 AST 吗?
  • 我仍然需要步行和分析 AST。由于这只是一项小任务,我仍然有点不愿意在这样的事情上投入几个小时的编码和测试。我不能成为第一个想知道变量是否写入某个文件且仅写入该文件的人。
  • @Lichtblitz 如果您认为静态预测程序在运行时执行的操作只是一项需要花费您几个小时的小任务(您不妨花在其他事情上),您可以低估了问题的难度。对于相当大的 C 子集,一个相当精确的静态分析器不应少于 10 人年。您将花费几个多小时才能找到已经完全按照您的意愿进行操作的十年人年分析仪,并使其以您想要的格式输出结果。除非您正在考虑基于正则表达式的语法解决方案
  • @PascalCuoq 我只是在寻找该十年分析仪的单个功能子集的一小部分。如果你读过我的文字,你就会知道我不关心价值观,甚至不关心可达性。我只想获取写入特定变量值的所有事件。例如,我只想找出特定变量恰好位于赋值左侧的所有位置。

标签: c++ c code-analysis static-code-analysis


【解决方案1】:

为什么不创建变量const,然后记下编译器禁止写访问的所有错误?

注意:这不会捕获变量底层内存以某种错误方式写入的错误,例如缓冲区溢出。

编辑:例如:

const int a = 1;
a = 2;
a = 3;

我的编译器生成:

1>MyProg.c(46): error C3892: 'a' : you cannot assign to a variable that is const
1>MyProg.c(47): error C3892: 'a' : you cannot assign to a variable that is const

【讨论】:

  • 嘿,这听起来不错。如果我想对多个变量执行此测试,我仍然需要自动化该过程以保持理智,但它听起来比自制解析器更可靠。
  • @Lichtblitz 您是否正在尝试整理某种关于写入变量的报告?我很想知道您为什么需要自动化它?
  • 如果你的意思是编译警告,编译器不会以这种方式列出所有对const变量的写入,如果你的意思是执行程序的运行时错误,问题是程序在第一次写入时停止。
  • @PascalCuoq 写入 const 变量是一个错误,除非你抛弃 const。显然有可能列举出这样的错误......见我的编辑:
  • 是的,编译器会为您展示的简单示例发出两个警告,但它只为 ideone.com/pMu4sy 发出一个警告。编译器不会显示对a 的所有写入,您甚至无法从“丢弃指针目标类型的限定符”警告中轻松推断出第一次写入,更不用说它们中的三个了。do得到。不过,您可以通过执行程序(但不是后者)获得第一次写入。这就是说,如果 OP 的程序看起来像您的示例,那么是的,他可以使用编译器警告。
【解决方案2】:

你的意思是这样的吗?

这适用于您努力使用Frama-C's value analysis 分析的 C 程序。它是开源的,依赖信息也可以通过编程方式获得。随着静态分析仪的发展,它处于频谱的“精确”一侧。如果您的目标是嵌入式 C 代码,它会更好地工作。

【讨论】:

  • 它是否也告诉我在哪里写入访问发生(文件/函数)?可能的值很高兴知道,但不是我对这项任务的主要关注。
  • 在这个截图中,它显示了用户感兴趣的变量S最后写在声明S += i;。之所以显示这些值,是因为它们也是计算出来的(在存在数组、指针数组的情况下,它们是回答问题所必需的......)但这里显示的(黄色)是定义 S 值的写入.
  • @PascalCuoq 它是否也会通过指针捕获写入,即int foo(int *) 称为foo(S)
  • @peterph 是的。这就是计算(整数变量和指针的)值的原因。从技术上讲,它是一种上下文敏感的路径敏感静态分析。
  • 好的,那我试试。感谢您的推荐:-)
【解决方案3】:

我不确定是否可以编写这样的工具。指针可用于更改内存中的任意数据,而无需引用指向该数据的其他变量。想想像 memset() 这样的函数,它会改变整个内存块。

如果您对这些类型的突变不感兴趣,您仍然需要考虑传递指针。在 C 语言中,您可以拥有任意数量的指向相同数据的指针,并且您必须分析这些指针的副本是在哪里制作的。然后这些副本可以再次复制,...

因此,即使在“简单”的情况下,也需要进行大量的代码分析。

【讨论】:

  • 哦,我忘了说代码库中没有指针算法。
  • 这可以让事情变得简单,但不会让事情变得微不足道。但@Benji 和 Antoine 提供的提示对我来说似乎是一个很好的解决方法。
  • 如果指针在变量地址初始化,它可以被显示(虽然有很多误报)。否则,在任意地址写入不会被捕获,但这是一个极端情况。
  • @Antoine 取决于它应该有多准确。在某些写入依赖于输入的情况下,它会变得非常困难,但您可以以“IF (Min
  • @peterph 你是对的,对于非平凡的情况,很难编写一个准确的工具。 llvm 的safe code 混合使用了静态和动态分析——尽管不完全针对同一个问题。
猜你喜欢
  • 2016-08-05
  • 2023-03-23
  • 2021-04-27
  • 2019-08-23
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 2011-11-11
相关资源
最近更新 更多