2017-02-15 157 views
0

我想实现一个分析(扩展DefaultOneStepAnalysis)在CHA算法中构造调用图。有我的代码三个部分组成:“findMethods”不返回预期的结果

1) method "doAnalyze" to return the "BasicReport" 
2) method "analyze" to find call edges for each method in the given project 
3) class "AnalysisContext" to store the context and methods using in the analysis. 

在3),我使用的方法“callBySignature”,找出相同“CHACallGraphExtractor”的方法cbsMethods但它不返回预期的结果。 虽然我使用原始OPAL的方式在提取器中获取cbsMethods,但结果是一组方法。

您能否帮我确认问题出在哪里以及如何解决? 非常感谢。

问候, 江

----我的代码的主要部分----------------------------- --------------------

object CHACGAnalysis extends DefaultOneStepAnalysis { 
    ... ... 
    override def doAnalyze(
            project: Project[URL], 
            parameters: Seq[String] = List.empty, 
            isInterrupted:() ⇒ Boolean 
           ): BasicReport = { 
    ... ... 
     for { 
      classFile <- project.allProjectClassFiles 
      method <- classFile.methods 
     } { 
     analyze(project, methodToCellCompleter, classFile, method)) 
     } 
    ... ... 
    } 

    def analyze(
       project: Project[URL], 
       methodToCellCompleter: Map[(String,Method), CellCompleter[K, Set[Method]]], 
       classFile: ClassFile, 
       method: Method 
       ): Unit = { 
    … … 
     val context = new AnalysisContext(project, classFile, method) 
     method.body.get.foreach((pc, instruction) ⇒ 
     instruction.opcode match { 
     ... ... 
      case INVOKEINTERFACE.opcode ⇒ 
       val INVOKEINTERFACE(declaringClass, name, descriptor) = instruction 
       context.addCallEdge_VirtualCall(pc, declaringClass, name, descriptor, true,cell1) 
      ... ... 
     } 
… … 
} 

protected[this] class AnalysisContext(
             val project: SomeProject, 
             val classFile: ClassFile, 
             val method: Method 
             ) { 
    val classHierarchy = project.classHierarchy 
    val cbsIndex = project.get(CallBySignatureResolutionKey) 
    val statistics = project.get(IntStatisticsKey) 
    val instantiableClasses = project.get(InstantiableClassesKey) 
    val cache = new CallGraphCache[MethodSignature, scala.collection.Set[Method]](project) 
private[AnalysisContext] def callBySignature(
                declaringClassType: ObjectType, 
                name:    String, 
                descriptor:   MethodDescriptor 
               ): Set[Method] = { 
     val cbsMethods = cbsIndex.findMethods(
     name, 
     descriptor, 
     declaringClassType 
    ) 
     cbsMethods 
    } 
def addCallEdge_VirtualCall(
           pc: PC, 
           declaringClassType: ObjectType, 
           name: String, 
           descriptor: MethodDescriptor, 
           isInterfaceInvocation: Boolean   = false, 
           cell1: CellCompleter[K, Set[Method]] 
           ): Unit = { 

     val cbsCalls = 
     if (isInterfaceInvocation) { 
      callBySignature(declaringClassType, name, descriptor) 
     } 
     else 
      Set.empty[Method] 

… … 
} 
… … 
} 
+0

您可以将您的代码添加到问题中吗?这将有助于澄清你的问题。 –

+0

当我上传代码的主要部分时,原始代码太复杂了。我也在OPAL中调试它,以找出为什么“cbsIndex.findMethods”找不到预期的方法。我发现它来自CallBySignatureResolution.scala中的“propertyStore(method,CallBySignature.Key)”。至于这个声明,我的代码的结果是“EP(XXXX,NoCBSTargets)”,原始代码的结果是“EP(XXX,CBSTargets(XXX))”。走得更远 –

+0

您的分析模式可能是桌面应用程序吗?你可以使用'project.analysisMode'来检查它 –

回答

1

最后,我发现这个问题是由于“AnalysisMode” 我重新AnalysisMode为“CPA“后,问题解决了。

我想我应该时刻记住在设计算法之前应该使用什么“AnalysisMode”。

谢谢您的关注 Jiang