OPAL:operandsArray 中的空值

OPAL: null-value in operandsArray

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

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

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

考虑到这一点,我构建了一个 DomainValues 的 IndexedSeq,并将其传递给执行方法 ob BaseAI。 它看起来像这样:

Vector({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, 空}[@-5;t=103]

堆栈索引 2:ADoubleValue

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

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

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

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

表示"this"

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

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

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

正在初始化局部变量

函数:org.opalj.ai.parameterToValueIndex只计算逻辑原点信息(与值关联的"pc",以便以后可以将各个值标识为参数)。

要正确地将操作数映射到局部变量,您可以使用方法 mapOperandsToParameters 或者您只需将所有值添加到 IndexedSeq 但为计算类型类别 2 值添加另一个 null 值.