0

我目前正在使用 OPAL 框架开发 Java 代码的静态分析。我想分析以下Java方法:

private void indirectCaller2b(double d, Object o1, Object o2) {
    indirectCaller1(d, o1, o2);
}

我知道,indirectCaller2b 仅使用参数(double、ArrayList、LinkedList)调用。

考虑到这一点,我构造了一个 DomainValues 的 IndexedSeq,我将它传递给 perform-method ob BaseAI。它看起来像这样:

向量({ai.native_methods_parameter_type_approximation.PublicClass, null}[@0;t=101], ADoubleValue, {_ <: java.util.ArrayList, null}[@-4;t=102], {_ <: java. util.LinkedList, null}[@-5;t=103])

这个参数 ({ai.native_methods_parameter_type_approximation.PublicClass, null}[@0;t=101]) 是使用以下代码创建的:

domain.TypedValue(0, project.classFile(caller).thisType)

其他域值是使用 parameterToValueIndex 方法创建的:

org.opalj.ai.parameterToValueIndex(caller.isStatic, caller.descriptor, index), t)

这里,caller 代表方法indirectCaller2b,t 是参数的已知运行时类型(参数索引1 的ArrayList 和参数索引2 的LinkedList)。

当我现在对方法进行抽象解释时

BaseAI.perform(classFile, caller, domain)(Some(parameters))

并在程序计数器上打印堆栈索引,indirectCaller1 的调用发生在以下代码中,

for (i <- 0 to analysisResult.operandsArray(pc).size - 1) {
      println(s"stack index $i: ${analysisResult.operandsArray(pc)(i)}")
}

我得到以下输出:

堆栈索引 0:空

堆栈索引 1: {_ <: java.util.LinkedList, null}[@-5;t=103]

堆栈索引 2:ADoubleValue

堆栈索引 3: {ai.native_methods_parameter_type_approximation.PublicClass, null}[@0;t=101]

这有点令人困惑,因为我只是将indirectCaller2b 的参数传递给了indirectCaller1。因此,输出应该与传递给 perform 方法的 IndexedSeq 相同。

但是在输出中,double 参数后面的参数是 LinkedList 而不是 ArrayList。ArrayList 参数不知何故消失了,operandStack 上的最后一个参数是“null”。

谁能解释一下,这怎么会发生?

4

1 回答 1

1

“这个”的表示

要获得“this”引用的正确表示,您应该使用该方法

InitializedObjectValue(
    origin:     ValueOrigin,
    objectType: ObjectType    ): DomainReferenceValue

创建 this 值的表示。不同之处在于,在这种情况下,AI 将尝试使用以下信息:(a)该值保证为非空,并且还保证被初始化。特别是前一个属性通常很有趣,并且通常会导致更精确的结果。

初始化局部变量

功能:org.opalj.ai.parameterToValueIndex仅计算逻辑原点信息(与值关联的“pc”,以便稍后将各个值识别为参数)。

要将操作数正确映射到本地,您可以使用该方法mapOperandsToParameters,也可以将所有值添加到 anIndexedSeq但为计算类型类别 2 值添加另一个null值。

于 2016-06-19T13:39:41.357 回答