2017-02-15 190 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