pascal-lab / Tai-e

An easy-to-learn/use static analysis framework for Java
https://tai-e.pascal-lab.net/docs/index.html
GNU Lesser General Public License v3.0
1.35k stars 171 forks source link

It is irrational that argument "--main-class" requires not null #7

Closed djaekim closed 1 year ago

djaekim commented 2 years ago

Hello =)

I am trying to run tai-e on a jar project I downloaded from this link. Specifically on commons-io-2.9.0-test-sources.jar.

To run this, I used following argument below.

This is the path of the .jar -cp "XXX/XX/jar/commons-io-2.9.0-test-sources.jar" This is the path of the .class file --input-classes="org/apache/commons/io/input/BoundedInputStreamTest.class" This is just trying to reproduce example posted on your documentation -a pta=cs:2-type;merge-string-constants:true

Unfortunately, I got errors below. I was wondering if you could help me to resolve this issue?

Tai-e starts ...
Writing options to output\options.yml
Writing analysis plan to output\tai-e-plan.yml
WorldBuilder starts ...
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.charAt(int)" because "option" is null
    at soot.options.Options.parse(Options.java:136)
    at soot.Main.processCmdLine(Main.java:85)
    at soot.Main.run(Main.java:248)
    at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:246)
    at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:73)
    at pascal.taie.Main.lambda$buildWorld$3(Main.java:121)
    at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
    at pascal.taie.util.Timer.runAndCount(Timer.java:93)
    at pascal.taie.util.Timer.runAndCount(Timer.java:111)
    at pascal.taie.util.Timer.runAndCount(Timer.java:107)
    at pascal.taie.Main.buildWorld(Main.java:116)
    at pascal.taie.Main.lambda$main$0(Main.java:55)
    at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
    at pascal.taie.util.Timer.runAndCount(Timer.java:93)
    at pascal.taie.util.Timer.runAndCount(Timer.java:111)
    at pascal.taie.util.Timer.runAndCount(Timer.java:107)
    at pascal.taie.Main.main(Main.java:48)

Process finished with exit code 1

Thank you so much!
zhangt2333 commented 2 years ago

This is the path of the .class file --input-classes="org/apache/commons/io/input/BoundedInputStreamTest.class"

An obvious issue is that argument --input-classes should follow the format of fully-qualified name in Java, e.g., org.apache.commons.io.input.BoundedInputStreamTest but not org/apache/commons/io/input/BoundedInputStreamTest.class.

djaekim commented 2 years ago

After changing it to fully qualified name. I still get the same error.

zhangt2333 commented 2 years ago

Could you provide the full arguments you used?

djaekim commented 2 years ago

Could you provide the fully arguments you used?

-cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes="org.apache.commons.io.input.BoundedInputStreamTest" -a pta=cs:2-type;merge-string-constants:true

Thank you!

zhangt2333 commented 2 years ago

-cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes="org.apache.commons.io.input.BoundedInputStreamTest" -a pta=cs:2-type;merge-string-constants:true

Hi!

-m is currently required not null (We will solve this issue shortly, then inform you).

In your scene, a temporary solution now is to choose one of --input-classes as -m. That is, with arguments -cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes=org.apache.commons.io.input.BoundedInputStreamTest -m org.apache.commons.io.input.BoundedInputStreamTest -a pta=cs:2-type;merge-string-constants:true, Tai-e will run normally.

djaekim commented 2 years ago

Hi thank you so much,

I tried to run it based on your suggestion with args below:

-cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes="org.apache.commons.io.input.BoundedInputStreamTest" -m "org.apache.commons.io.input.BoundedInputStreamTest" -a pta=cs:2-type;merge-string-constants:true

However, there was another error

Exception in thread "main" soot.JavaClassProvider$JarException: Class org.apache.commons.io.input.BoundedInputStreamTest was found in an archive, but Soot doesn't support reading source files out of an archive
    at soot.JavaClassProvider.find(JavaClassProvider.java:75)
    at soot.SourceLocator.getClassSource(SourceLocator.java:187)
    at soot.Scene.tryLoadClass(Scene.java:969)
    at soot.Scene.loadBasicClasses(Scene.java:1713)
    at soot.Scene.loadNecessaryClasses(Scene.java:1806)
    at soot.Main.run(Main.java:254)
    at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)

Thank you, kim

zhangt2333 commented 2 years ago

I will take a deep look at this issue later.

Currently, a workaround is to pass the decompressed directory (not a jar file) as class path.

zhangt2333 commented 1 year ago
Exception in thread "main" soot.JavaClassProvider$JarException: Class org.apache.commons.io.input.BoundedInputStreamTest was found in an archive, but Soot doesn't support reading source files out of an archive
  at soot.JavaClassProvider.find(JavaClassProvider.java:75)
  at soot.SourceLocator.getClassSource(SourceLocator.java:187)
  at soot.Scene.tryLoadClass(Scene.java:969)
  at soot.Scene.loadBasicClasses(Scene.java:1713)
  at soot.Scene.loadNecessaryClasses(Scene.java:1806)
  at soot.Main.run(Main.java:254)
  at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)

In the above exception, the Soot’s frontend doesn't support reading Java source files out of an archive. So we need pass the decompressed directory (but not a jar) as class path.

In addition, as stated below, we recommend analyzing the bytecode for real-world program. In your case, is that using commons-io-2.9.0-tests.jar instead of commons-io-2.9.0-test-sources.jar? Maybe so, I guess.

Soot’s frontend for Java source files is outdated (only partially supports Java version up to 7) and not very robust. Meanwhile, Soot’s frontend for bytecode files, which does not keep variable names though, is more robust (it virtually works well for the .class files compiled by up to Java 17) than the frontend for Java source files. Thus, for real-world applications, Tai-e usually analyzes bytecode.

zhangt2333 commented 1 year ago

-m is currently required not null (We will solve this issue shortly, then inform you).

After the commit https://github.com/pascal-lab/Tai-e/commit/d9784e3ae64286fc87eea10e1b551204772e2b34, it only requires that at least one of --main-class and --input-classes be specifie.

That means -m can be ignored in your case. (You can try on the latest commit)

zhangt2333 commented 1 year ago

No response for more than 7 days.

Closing now.

djaekim commented 1 year ago

Hello, I apologize for the delay.

For running real world project, I want to run, for instance, inter-procedural analysis for each individual Junit Test Case to see how data might flow from and to the specific test case.

To do this, I want to get minimal execution using existing analyzer before writing some custom analyzer. I am still having trouble running this.

If I want to analyze a specific Junit method (not necessarily static main method), how would I go about instrumenting it?

Currently, my cmd looks like this -cp C:\Users\djaek\Documents\PhD\Inheritance\inheritance_extractor\analysis_python\jar\some.jar ----input-classes=org.apache.commons.io.input.BoundedInputStreamTest -a pta=cs:2-type;merge-string-constants:true

However, there was issue with was that it must be decompressed or something.

I was wondering, what would be the exact step to go about this?

zhangt2333 commented 1 year ago

If I want to analyze a specific Junit method (not necessarily static main method), how would I go about instrumenting it?

see https://github.com/pascal-lab/Tai-e/issues/9.

However, there was issue with was that it must be decompressed or something.

It is not clear I cannot get what you mean. Exception infomation should be provided if it exists.

djaekim commented 1 year ago

Hi, I am still getting the same error, when executing command below

--class-path
C:\\Users\\djaek\\Documents\\PhD\\Inheritance\\inheritance_extractor\\analysis_python\\jar\\commons-collections\\
--input-classes=org.apache.commons.collections4.functors.AllPredicateTest
--analysis
pta=cs:2-type

the -class-path is the directory to bytecode

"C:\Program Files\Java\jdk-18.0.2\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:55685,suspend=y,server=n -javaagent:C:\Users\djaek\AppData\Local\JetBrains\IdeaIC2022.2\captureAgent\debugger-agent.jar=file:/C:/Users/djaek/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath "C:\Users\djaek\Documents\...\analysis_python\Snapshot_Analysis\Tai-e\out\production\classes;C:\Users\djaek\Documents\...\Snapshot_Analysis\Tai-e\out\production\resources;C:\Users\djaek\Documents\...\Snapshot_Analysis\Tai-e\lib\sootclasses-modified.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\info.picocli\picocli\4.6.1\49a67ee4b4d9722fa60f3f9ffaffa72861c32966\picocli-4.6.1.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-core\2.16.0\ca12fb3902ecfcba1e1357ebfc55407acec30ede\log4j-core-2.16.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.16.0\4727d93a76616ffc4149dffac5801827c0f4ac71\log4j-api-2.16.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.dataformat\jackson-dataformat-yaml\2.12.2\8c549fb29f390f6fd0c20cf0a1d83f7e38dc7ffb\jackson-dataformat-yaml-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.soot-oss\soot\4.3.0-20211223.212205-256\649b6b2af64434fb2659343f06d2893cd25ace91\soot-4.3.0-20211223.212205-256.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-nop\1.7.5\3482f4546a52dc63d0c8e829338f26a77e5eab1b\slf4j-nop-1.7.5.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.12.2\5f9d79e09ebf5d54a46e9f4543924cf7ae7654e0\jackson-databind-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.12.2\8df50138521d05561a308ec2799cc8dda20c06df\jackson-core-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.27\359d62567480b07a679dc643f82fc926b100eed5\snakeyaml-1.27.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.7\3f2bd4ba11c4162733c13cc90ca7c7ea09967102\commons-io-2.7.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.smali\dexlib2\2.5.2\8b664182af455b0757a7f59a42020fa5608c7d0e\dexlib2-2.5.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-util\9.2\fbc178fc5ba3dab50fd7e8a5317b8b647c8e8946\asm-util-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-commons\9.2\f4d7f0fc9054386f2893b602454d48e07d4fbead\asm-commons-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-tree\9.2\d96c99a30f5e1a19b0e609dbb19a44d8518ac01e\asm-tree-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm\9.2\81a03f76019c67362299c40e0ba13405f5467bff\asm-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\xmlpull\xmlpull\1.1.3.4d_b4_min\6dcdbef481ff8fbac336a47048048b2b31855015\xmlpull-1.1.3.4d_b4_min.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\de.upb.cs.swt\axml\2.1.0-SNAPSHOT\32374202d6343f6d0de434918469aa7316017168\axml-2.1.0-SNAPSHOT.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\ca.mcgill.sable\polyglot\2006\f0e528051faa260d83f53d58275954d973231ce7\polyglot-2006.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\de.upb.cs.swt\heros\1.2.3-SNAPSHOT\bdea1884d3f1ec9d57dbc03ca99cb17ef5c0819d\heros-1.2.3-SNAPSHOT.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\ca.mcgill.sable\jasmin\3.0.3-SNAPSHOT\573ac2f66d968fd40898b6458e888f2b56351e1d\jasmin-3.0.3-SNAPSHOT.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.32\cdcff33940d9f2de763bc41ea05a0be5941176c3\slf4j-api-1.7.32.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\javax.annotation\javax.annotation-api\1.3.2\934c04d3cfef185a8008e7bf34331b79730a9d43\javax.annotation-api-1.3.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\jaxb-runtime\2.4.0-b180830.0438\2a0705ce8aa988b691c70e8bdcc1613050a148a2\jaxb-runtime-2.4.0-b180830.0438.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\javax.xml.bind\jaxb-api\2.4.0-b180830.0359\b54184b7dcab2031add3f525550c7f1b7e12209d\jaxb-api-2.4.0-b180830.0359.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.12.2\a770cc4c0a1fb0bfd8a150a6a0004e42bc99fca\jackson-annotations-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-analysis\9.2\7487dd756daf96cab9986e44b9d7bcb796a61c10\asm-analysis-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.functionaljava\functionaljava\4.2\f26bdd90a8d6b6faeb38ab2ba4c39580c1eb989f\functionaljava-4.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\ca.mcgill.sable\java_cup\0.9.2\f36b758580fb9d472bfd5965aa9ac807fa66d242\java_cup-0.9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\javax.activation\javax.activation-api\1.2.0\85262acf3ca9816f9537ca47d5adeabaead7cb16\javax.activation-api-1.2.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\txw2\2.4.0-b180830.0438\31bae7fb5924472b3243b265b47cb741da715419\txw2-2.4.0-b180830.0438.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.sun.istack\istack-commons-runtime\3.0.7\c197c86ceec7318b1284bffb49b54226ca774003\istack-commons-runtime-3.0.7.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.jvnet.staxex\stax-ex\1.8\8cc35f73da321c29973191f2cf143d29d26a1df7\stax-ex-1.8.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.sun.xml.fastinfoset\FastInfoset\1.2.15\bb7b7ec0379982b97c62cd17465cb6d9155f68e8\FastInfoset-1.2.15.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.guava\failureaccess\1.0.1\1dcf1de382a0bf95a3d8b0849546c88bac1292c9\failureaccess-1.0.1.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\b421526c5f297295adef1c886e5246c39d4ac629\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.code.findbugs\jsr305\3.0.2\25ea2e8b0c338a877313bd4672d3fe056ea78f0d\jsr305-3.0.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.guava\guava\27.1-android\a80ef47421d6607e749f8b7282dd7dee61adfea7\guava-27.1-android.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.checkerframework\checker-compat-qual\2.5.2\dc0b20906c9e4b9724af29d11604efa574066892\checker-compat-qual-2.5.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.errorprone\error_prone_annotations\2.2.0\88e3c593e9b3586e1c6177f89267da6fc6986f0c\error_prone_annotations-2.2.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.j2objc\j2objc-annotations\1.1\ed28ded51a8b1c6b112568def5f4b455e6809019\j2objc-annotations-1.1.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.codehaus.mojo\animal-sniffer-annotations\1.17\f97ce6decaea32b36101e37979f8b647f00681fb\animal-sniffer-annotations-1.17.jar;C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2022.2.1\lib\idea_rt.jar" pascal.taie.Main --class-path "C:\\Users\\djaek\\Documents\\...\\jar\\commons-collections\\\\" --input-classes=org.apache.commons.collections4.functors.AllPredicateTest --analysis pta=cs:2-type;only-app:true
Connected to the target VM, address: '127.0.0.1:55685', transport: 'socket'
Tai-e starts ...
Writing options to output\options.yml
Writing analysis plan to output\tai-e-plan.yml
WorldBuilder starts ...
java-benchmarks\JREs\jre1.6\jce.jar;java-benchmarks\JREs\jre1.6\jsse.jar;java-benchmarks\JREs\jre1.6\rt.jar;C:\\Users\\djaek\\Documents\\PhD\\Inheritance\\inheritance_extractor\\analysis_python\\jar\\commons-collections\\
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.charAt(int)" because "option" is null
    at soot.options.Options.parse(Options.java:136)
    at soot.Main.processCmdLine(Main.java:85)
    at soot.Main.run(Main.java:248)
    at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)
    at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:74)
    at pascal.taie.Main.lambda$buildWorld$3(Main.java:121)
    at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
    at pascal.taie.util.Timer.runAndCount(Timer.java:93)
    at pascal.taie.util.Timer.runAndCount(Timer.java:111)
    at pascal.taie.util.Timer.runAndCount(Timer.java:107)
    at pascal.taie.Main.buildWorld(Main.java:116)
    at pascal.taie.Main.lambda$main$0(Main.java:55)
    at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
    at pascal.taie.util.Timer.runAndCount(Timer.java:93)
    at pascal.taie.util.Timer.runAndCount(Timer.java:111)
    at pascal.taie.util.Timer.runAndCount(Timer.java:107)
    at pascal.taie.Main.main(Main.java:48)
Disconnected from the target VM, address: '127.0.0.1:55685', transport: 'socket'

Finally, I really appreciate the documentations, but I am still having trouble running a simple example. I was wondering if it would be possible to make available some kind of complete example on analyzing a real world apache project, where it runs some reproducible analysis example from start to finish. I feel like this would help make better accessibility of the features. Thank you.

zhangt2333 commented 1 year ago
  at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)
  at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:74)

I notice that the line number of method runSoot in the stack frame is line 247.

It seems to imply that the Tai-e you are using is under this commit https://github.com/pascal-lab/Tai-e/commit/9d9d15a0a1ba9b63801d41e18041ec046d868df9 but not https://github.com/pascal-lab/Tai-e/commit/d9784e3ae64286fc87eea10e1b551204772e2b34 (as I mentioned in https://github.com/pascal-lab/Tai-e/issues/7#issuecomment-1250431443).

https://github.com/pascal-lab/Tai-e/blob/9d9d15a0a1ba9b63801d41e18041ec046d868df9/src/main/java/pascal/taie/frontend/soot/SootWorldBuilder.java#L244-L248

https://github.com/pascal-lab/Tai-e/blob/d9784e3ae64286fc87eea10e1b551204772e2b34/src/main/java/pascal/taie/frontend/soot/SootWorldBuilder.java#L252-L256

Could you pull the latest code and try it again?

djaekim commented 1 year ago
    at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)
    at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:74)

I notice that the line number of method runSoot in the stack frame is line 247.

It seems to imply that the Tai-e you are using is under this commit 9d9d15a but not d9784e3 (as I mentioned in #7 (comment)).

https://github.com/pascal-lab/Tai-e/blob/9d9d15a0a1ba9b63801d41e18041ec046d868df9/src/main/java/pascal/taie/frontend/soot/SootWorldBuilder.java#L244-L248

https://github.com/pascal-lab/Tai-e/blob/d9784e3ae64286fc87eea10e1b551204772e2b34/src/main/java/pascal/taie/frontend/soot/SootWorldBuilder.java#L252-L256

Could you pull the latest code and try it again?

Thank you, it's working now.

Another question I have is I want to use plugin to analyze specific Junit Test Method. What is the general step done to do that? I tried to use existing plugin just as a proof-of-concept. Tai-e\src\main\java\pascal\taie\analysis\pta\plugin\taint\TaintAnalysis.java

For example, let's say my -input-classes="some test.java file to analyze". To access this class's Junit method in the in the TaintAnalysis's onStart to add to the solver.addEntryPoint(), I used below code. It that ok?

        Iterable<JClass> iterable = World.get().getClassHierarchy().applicationClasses()::iterator;
        for (JClass s : iterable) {
           for(JMethod m : s.getDeclaredMethods()){
               solver.addEntryPoint(new EntryPoint(m,
                       new MainEntryPointParamProvider(m, solver)));
           }
        }

I am also using

-cp
\repo\dubbo\
--input-classes=dubbo-cluster.target.test-classes.org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalanceTest
-a
"pta=action:dump;action-file:output.dump"
-ap
-scope
REACHABLE  

I used -ap because I only want to analyze specific junit file, but this file depends on other files. Would this affect analysis? For example, I got the below logs. image

Another question I have is, for this above analysis, it gave an output.dump that is for entire source code, but not the specified files. How to only get output for the specified files?

zhangt2333 commented 1 year ago

Another question I have is I want to use plugin to analyze specific Junit Test Method. What is the general step done to do that?

Refer to wiki, https://github.com/pascal-lab/Tai-e/issues/9, write a plugin of your own, and activate it.

For example, let's say my -input-classes="some test.java file to analyze". To access this class's Junit method in the in the TaintAnalysis's onStart to add to the solver.addEntryPoint(), I used below code. It that ok?

        Iterable<JClass> iterable = World.get().getClassHierarchy().applicationClasses()::iterator;
        for (JClass s : iterable) {
           for(JMethod m : s.getDeclaredMethods()){
               solver.addEntryPoint(new EntryPoint(m,
                       new MainEntryPointParamProvider(m, solver)));
           }
        }

It seems that this would treat all methods of all classes in the World (the classes being analyzed) as public static void main(String[] args). I don't think it's what you want. Maybe you can take the following steps:

  1. Gets the specific class from ClassHierarchy, e.g., by World.get().getClassHierarchy().getClass("org.apache.commons.collections4.functors.AllPredicateTest");

  2. Gets all methods in the class and filters out the ones with the @Test annotation. May need to use pascal.taie.language.classes.JClass#getDeclaredMethods and pascal.taie.language.classes.ClassMember#hasAnnotation.

  3. Adds entrypoint by pascal.taie.analysis.pta.core.solver.Solver#addEntryPoint. Note that you may need to mock the parameters of the method. See also pascal.taie.analysis.pta.core.solver.ParamProvider and its three subclasses.

I used -ap because I only want to analyze specific junit file, but this file depends on other files. Would this affect analysis? For example, I got the below logs. image

See https://github.com/pascal-lab/Tai-e/issues/3.

Another question I have is, for this above analysis, it gave an output.dump that is for entire source code, but not the specified files. How to only get output for the specified files?

There is no option to support this action. If you want to filter the pointers to be dumped, consider modifying the following code:

https://github.com/pascal-lab/Tai-e/blob/283d1ef5a4316232dc01fd7e454758e3ece88cfc/src/main/java/pascal/taie/analysis/pta/plugin/ResultProcessor.java#L178-L185