Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fail to find CGNode in call graph #1160

Closed
xxwxxwen opened this issue Nov 27, 2022 · 8 comments
Closed

fail to find CGNode in call graph #1160

xxwxxwen opened this issue Nov 27, 2022 · 8 comments

Comments

@xxwxxwen
Copy link

I build call graph for the test class,and can find testWithString method in the call graph, but I failed to find testWithInputStream and testWithGenerator method in the call graph,is it because of the parameter of the method(@from)? How can I find testWithGenerator CGNode in call graph?
Here is my Junit test class
Screenshot from 2022-11-27 05-04-21
for (CGNode n : cg) {
if(n.toString().equals("Node: < Application, LProjectBuilderTest, testWithGenerator(Lorg/w3c/dom/Document;)V >"))
System.out.println(n);
}

@xxwxxwen
Copy link
Author

@msridhar Could you please give me a reply at your convenience? It is really important to me.Thanks a lot!

@msridhar
Copy link
Member

To find a method in the call graph it either needs to be called from another method in the call graph or it needs to be an entry point. Which case is this one?

@xxwxxwen
Copy link
Author

@msridhar This is a Junit test, and I set testWithGenerator as entry point,but can't find testWithGenerator in call graph.I have read com.ibm.wala.core.util.scope.JUnitEntryPoints.What's the problem with the following code? How to set entry point for JUnitEntryPoints?
Screenshot from 2022-11-28 05-54-52

@msridhar
Copy link
Member

@xxwxxwen can you please post the code itself rather than screenshots? Screenshots are very difficult to read and I cannot copy-paste from them. You can enclose the code with "```java" for syntax highlighting, e.g.:

class Foo { ... }

@xxwxxwen
Copy link
Author

I want to set test method name contains "test"(e.g. testWithGenerator or testWithInputStream) as EntryPoint. It is a Junit test. However,I failed to find testWithGenerator method in call graph.
This is my code

public static CallGraph makeCallGraph(String Path) throws IOException, ClassHierarchyException, CallGraphBuilderCancelException, InvalidClassFileException {
      String inputFile = path;
      File exclusionsFile = new File("/home/xxw/Downloads/Demo/Exclusions.txt");
        scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(inputFile, exclusionsFile);

        cha = ClassHierarchyFactory.make(scope);
       
        Iterable<Entrypoint> entryPoints =findFuzzMethod();
//      options.setEntrypoints(entryPoints);
        AnalysisOptions options = new AnalysisOptions(scope, entryPoints);
         options.setReflectionOptions(AnalysisOptions.ReflectionOptions.NONE);
        AnalysisCache cache = new AnalysisCacheImpl();
    
        CallGraphBuilder cgBuilder = Util.makeZeroOneCFABuilder(Language.JAVA,options, new AnalysisCacheImpl(), cha, scope);

        return cgBuilder.makeCallGraph(options,null);
 }

public static Iterable<Entrypoint> findFuzzMethod() {
        final HashSet<Entrypoint> result = HashSetFactory.make();
        if (cha != null) {
            for (IClass klass : cha) {
            IClassLoader classLoader = klass.getClassLoader();
            ClassLoaderReference reference = classLoader.getReference();
            if (reference.equals(ClassLoaderReference.Application)) {
                boolean isTestClass = false;

            for (com.ibm.wala.classLoader.IMethod method : klass.getDeclaredMethods()) {

                if (!(method instanceof ShrikeCTMethod))
                    continue;

                for (Annotation annotation : ((ShrikeCTMethod) method).getAnnotations()) {
                    if (method.getDeclaringClass().getName().toString().substring(1).equals(testClassName)) {
                        if (method.getName().toString().equals("testWithGenerator")) {
                            System.out.println(method.getName());
                        }

                        result.add(new DefaultEntrypoint(method, cha));
                        isTestClass = true;
                    }
                }
            }

            if (isTestClass) {
                IMethod classInitializer = klass.getClassInitializer();
                if (classInitializer != null)
                    result.add(new DefaultEntrypoint(classInitializer, cha));
                IMethod ctor = klass.getMethod(MethodReference.initSelector);
                if (ctor != null)
                    result.add(new DefaultEntrypoint(ctor, cha));
            }
          }
         }
        }
        return result::iterator;
    }

 public void Analysis() throws InvalidClassFileException {
   for (CGNode n : cg) {
      if(n.toString().equals("Node: < Application, L/.../Test, testWithInputStream(Ljava/io/InputStream;)V > Context: Everywhere"))
      System.out.println(n);
// Assert.assertTrue(n.toString().equals("Node: < Application, L/.../Test, testWithInputStream(Ljava/io/InputStream;)V > Context: Everywhere"));
    }
// n is null,could not find testWithGenerator or tesWithInputStream method ,and could not get control flow graph
   if(n!=null) {
    SSACFG cfg = cn.getIR().getControlFlowGraph();
    getNextBlock(cfg, cn, lineNum);
   }

   Iterator<CGNode> iter = cg.iterator();
   CGNode node;
   while(iter.hasNext()){
      node = iter.next();
      TypeName tempType = node.getMethod().getDeclaringClass().getName();
    if(tempType.toString().equals("L/.../Test")){
      System.out.println(node);
    }
   }

}

This is my test program
@RunWith(JQF.class)
public class Test {

    @Fuzz
    public void testWithInputStream(InputStream inputStream) throws IOException {
        JavaClass clazz;
        try {
            clazz = new ClassParser(inputStream, "Hello.class").parse();
        } catch (ClassFormatException e) {
            // ClassFormatException thrown by the parser is just invalid input
            Assume.assumeNoException(e);
            return;
        }

        // Any non-IOException thrown here should be marked a failure
        // (including ClassFormatException)
        verifyJavaClass(clazz);
    }

    @Fuzz
    public void testWithGenerator(@From(JavaClassGenerator.class) JavaClass javaClass) throws IOException {

        try {
            // Dump the javaclass to a byte stream and get an input pipe
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            javaClass.dump(out);

            ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
            testWithInputStream(in);
        } catch (ClassFormatException e) {
            throw e;
        }
    }
}

Is there something wrong with findFuzzMethod() when set EntryPoint? I could not find testWithGenerator in call graph.How to define EntryPoint for Junit test? Thanks a lot for your help 

@msridhar
Copy link
Member

I am not sure the built-in com.ibm.wala.core.util.scope.JUnitEntryPoints class will work with your test code, so it's good that you are writing your own logic to detect entrypoints. This is the logic in JUnitEntryPoints for detecting test methods by name (m is an IMethod):

Atom method = m.getName();
String methodName = method.toString();
return methodName.startsWith("test")
|| methodName.equals("setUp")
|| methodName.equals("tearDown");
}

So I would mimick that. It looks like your code is uselessly iterating over method annotations, so I would get rid of that. Other than that, I think just debug your code, add some prints, and make sure the findFuzzMethod() code is actually finding the method you want. If you add it as an entrypoint, I am confident it will be in the call graph.

@xxwxxwen
Copy link
Author

@msridhar Thank you for your help! Wala can generate call graph from Jar file,how can I generate Jar file from my project? Does it only need include test classes? I want to generate a Jar file for a few test classes,and analysis the invoke chain. But how to build call graph among different classes?
Can wala build call graph directly from source zip code or binary zip code.Some classes in zip may not have methods, only have some fields.How can I build call graph for ant( https://ant.apache.org ) .
I don't have a good understanding of this, so I may ask too simple questions. Thank you for your help.

@msridhar
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants