C++ 监控C/C+中的变量访问+;

C++ 监控C/C+中的变量访问+;,c++,c,clang,code-coverage,C++,C,Clang,Code Coverage,我正在研究多线程代码的覆盖率标准,作为其中的一部分,我希望记录对变量的访问。例如,在下面的代码中,我想记录变量x被写入,并且y,z,a[I],和I被读取 x = y * (int)z + a[i] 我一直在考虑使用Clang的RecursiveASTVisitor来实现这一点,并修改源代码以包含录制功能。然而,我不确定这是否是一种明智的方法,因为我对Clang如何工作的理解非常不完整 目前,当我找到一条语句时,我会检查它是二进制运算符、UnaryOperator、Cast还是DeclRefEx

我正在研究多线程代码的覆盖率标准,作为其中的一部分,我希望记录对变量的访问。例如,在下面的代码中,我想记录变量
x
被写入,并且
y,z,a[I],
和I被读取

x = y * (int)z + a[i]
我一直在考虑使用Clang的RecursiveASTVisitor来实现这一点,并修改源代码以包含录制功能。然而,我不确定这是否是一种明智的方法,因为我对Clang如何工作的理解非常不完整

目前,当我找到一条语句时,我会检查它是
二进制运算符、UnaryOperator、Cast还是DeclRefExpr
。(一旦基本操作完成,我将扩展它的功能。)如果它是
二进制运算符、unary运算符或Cast
,我将检查表达式的子表达式。如果它是DeclRefExpr,我可以检查表达式是左值还是右值(现在再次简化),但一旦找到DeclRefExpr,它们总是左值。为了确定它们是用作
左值还是右值
我必须检查它的父项,如果它是左值强制转换,则它被用作右值

我觉得我对这个问题采取了错误的方法,因为我只能看到它变得更加复杂,因为我必须考虑更复杂的代码。

有没有更好的办法

多谢各位

编辑

我不打算静态地记录这些信息。我打算找到变量的用法,并插入代码,在代码运行时记录对这些变量的访问

例如,给定上面的代码(
x=y*(int)z+a[i];
),我希望生成如下内容

x = y * (int)z + a[i];
recordAccess(<file>, <line>, "x",    &x,    WRITE);
recordAccess(<file>, <line>, "y",    &y,    READ);
recordAccess(<file>, <line>, "z",    &z,    READ);
recordAccess(<file>, <line>, "a[i]", &a[i], READ);
recordAccess(<file>, <line>, "i",    &i,    READ);
x=y*(int)z+a[i];
记录访问(,“x”,&x,写入);
记录访问(,“y”,&y,读取);
记录访问(,“z”,&z,读取);
记录存取(,“a[i]”,&a[i],读取);
记录访问(,“i”,&i,读取);

这里的主要问题是您没有考虑使用别名。您将只能记录简单、直接的访问


但在这种情况下,一个简单的表达是主要的方法。但是Clang的RecursiveASTVisitor应该能够从内存中为您省去麻烦,并允许您直接访问最终的变量节点。毕竟,它应该访问每一个AST节点。

正如其他人所指出的,别名使得这不可能。静态分析代码以回答您感兴趣的问题是不可能的。如果可以通过分析语法获取源代码文件并确定输出,编译器将生成结果程序的输出,而不是编译程序的输出。简言之,您正试图回答这个问题


动态分析是回答您最感兴趣的问题所需要的。多线程软件的动态分析已经有了很大的市场

你的第一个评论当然是我需要解决的问题,但我从更基本的东西开始。虽然访问了每个AST节点,但我仍然不确定如何确定如何使用它。例如,仅仅检查它的父节点是否是右值转换的左值就足够了吗?@tgt:我不这么认为。考虑函数调用FO(x),x定义为引用参数。x是读的还是写的?如果不检查foo的主体,你就无法判断(甚至这可能还不够,因为foo可能(复杂地图灵)调用其他东西。更复杂的是,foo主体的定义可能不在同一个编译单元中;那么你将如何检查它?很难为此实现动态分析(并非不可能,但也很难)。本质上,您必须用数据访问收集机制替换每个编译单元中的每个指针访问,该机制可以以某种方式捕获引用实体的源代码位置。(我们使用检查点工具来实现这一点[唉,目前仅限于C).我同意!我想向OP指出的是,尽管他或她已经制定了一个理性的、经过深思熟虑的问题状态,但找到解决方案并不是那么简单。想要分析对内存区域的多线程访问是完全合乎逻辑的。然而,这并不像听起来那么简单。上次我看到的是,Portland Group had为这类事情开发了产品。然而,我从未有过与他们合作的乐趣。您想为:*p=0;?您希望如何确定正在修改的变量名?recordAccess(,“*p”,p,WRITE)我想。这并不是你声称想要做的。首先,它是对变量p的访问。其次,它没有列出变量(或分配的堆块)在C++和C++中,指针是非常常见的。我不完全确定你的意思。我会记录P正在被读取,并且P正在被写入,并且从其他访问到P指向的地址,我知道哪些其他变量访问该内存。你会提供一个例子吗?你在描述什么?